diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 74e2a26202..392a527094 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -320,6 +320,11 @@
"toolbar": {
"search": "Search"
}
+ },
+ "undo": {
+ "undo": "Undo Edit",
+ "undoDialog": "Undo this edit?",
+ "undoDisabled": "Undo Unavailable"
}
},
"charInventory": {
diff --git a/src/components/App/DefaultState.ts b/src/components/App/DefaultState.ts
index 1290da98da..2b83b867e2 100644
--- a/src/components/App/DefaultState.ts
+++ b/src/components/App/DefaultState.ts
@@ -7,7 +7,7 @@ import { defaultState as pronunciationsState } from "components/Pronunciations/R
import { defaultState as treeViewState } from "components/TreeView/Redux/TreeViewReduxTypes";
import { defaultState as characterInventoryState } from "goals/CharacterInventory/Redux/CharacterInventoryReducer";
import { defaultState as mergeDuplicateGoal } from "goals/MergeDuplicates/Redux/MergeDupsReducer";
-import { defaultState as reviewEntriesState } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
+import { defaultState as reviewEntriesState } from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import { defaultState as analyticsState } from "types/Redux/analyticsReduxTypes";
export const defaultState = {
diff --git a/src/components/DataEntry/DataEntryTable/NewEntry/SenseDialog.tsx b/src/components/DataEntry/DataEntryTable/NewEntry/SenseDialog.tsx
index 11132c97f4..67255d1904 100644
--- a/src/components/DataEntry/DataEntryTable/NewEntry/SenseDialog.tsx
+++ b/src/components/DataEntry/DataEntryTable/NewEntry/SenseDialog.tsx
@@ -14,8 +14,8 @@ import StyledMenuItem from "components/DataEntry/DataEntryTable/NewEntry/StyledM
import {
DomainCell,
PartOfSpeechCell,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
import { firstGlossText } from "utilities/wordUtilities";
interface SenseDialogProps {
diff --git a/src/components/DataEntry/DataEntryTable/NewEntry/VernDialog.tsx b/src/components/DataEntry/DataEntryTable/NewEntry/VernDialog.tsx
index 77e96dc084..bb977365aa 100644
--- a/src/components/DataEntry/DataEntryTable/NewEntry/VernDialog.tsx
+++ b/src/components/DataEntry/DataEntryTable/NewEntry/VernDialog.tsx
@@ -15,8 +15,8 @@ import {
DomainCell,
GlossCell,
PartOfSpeechCell,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
interface vernDialogProps {
vernacularWords: Word[];
diff --git a/src/components/DataEntry/DataEntryTable/NewEntry/tests/SenseDialog.test.tsx b/src/components/DataEntry/DataEntryTable/NewEntry/tests/SenseDialog.test.tsx
index 88e6cc85b0..4451a9fc20 100644
--- a/src/components/DataEntry/DataEntryTable/NewEntry/tests/SenseDialog.test.tsx
+++ b/src/components/DataEntry/DataEntryTable/NewEntry/tests/SenseDialog.test.tsx
@@ -16,7 +16,7 @@ import { defaultWritingSystem } from "types/writingSystem";
// MUI: Unable to set focus to a MenuItem whose component has not been rendered.
jest.mock("@mui/material/MenuItem", () => "div");
-jest.mock("goals/ReviewEntries/ReviewEntriesComponent/CellComponents", () => ({
+jest.mock("goals/ReviewEntries/ReviewEntriesTable/CellComponents", () => ({
DomainCell: () =>
,
PartOfSpeechCell: () => ,
}));
diff --git a/src/components/DataEntry/DataEntryTable/NewEntry/tests/VernDialog.test.tsx b/src/components/DataEntry/DataEntryTable/NewEntry/tests/VernDialog.test.tsx
index d52584e437..51eb3cb09c 100644
--- a/src/components/DataEntry/DataEntryTable/NewEntry/tests/VernDialog.test.tsx
+++ b/src/components/DataEntry/DataEntryTable/NewEntry/tests/VernDialog.test.tsx
@@ -16,7 +16,7 @@ import { defaultWritingSystem } from "types/writingSystem";
// MUI: Unable to set focus to a MenuItem whose component has not been rendered.
jest.mock("@mui/material/MenuItem", () => "div");
-jest.mock("goals/ReviewEntries/ReviewEntriesComponent/CellComponents", () => ({
+jest.mock("goals/ReviewEntries/ReviewEntriesTable/CellComponents", () => ({
DomainCell: () => ,
GlossCell: () => ,
PartOfSpeechCell: () => ,
diff --git a/src/components/GoalTimeline/Redux/GoalActions.ts b/src/components/GoalTimeline/Redux/GoalActions.ts
index e583c63cb6..5d9cc898e4 100644
--- a/src/components/GoalTimeline/Redux/GoalActions.ts
+++ b/src/components/GoalTimeline/Redux/GoalActions.ts
@@ -18,7 +18,7 @@ import {
} from "components/GoalTimeline/Redux/GoalReducer";
import { CharacterChange } from "goals/CharacterInventory/CharacterInventoryTypes";
import { dispatchMergeStepData } from "goals/MergeDuplicates/Redux/MergeDupsActions";
-import { EntryEdit } from "goals/ReviewEntries/ReviewEntries";
+import { EntryEdit } from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreState } from "types";
import { StoreStateDispatch } from "types/Redux/actions";
import { Goal, GoalStatus, GoalType } from "types/goals";
diff --git a/src/components/GoalTimeline/Redux/GoalReducer.ts b/src/components/GoalTimeline/Redux/GoalReducer.ts
index 44915b3725..a54b8b3141 100644
--- a/src/components/GoalTimeline/Redux/GoalReducer.ts
+++ b/src/components/GoalTimeline/Redux/GoalReducer.ts
@@ -5,7 +5,10 @@ import {
MergeDupsData,
MergesCompleted,
} from "goals/MergeDuplicates/MergeDupsTypes";
-import { EntriesEdited, EntryEdit } from "goals/ReviewEntries/ReviewEntries";
+import {
+ EntriesEdited,
+ EntryEdit,
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreActionTypes } from "rootActions";
import { GoalType } from "types/goals";
diff --git a/src/goals/DefaultGoal/BaseGoalScreen.tsx b/src/goals/DefaultGoal/BaseGoalScreen.tsx
index 06dd04668b..61338138be 100644
--- a/src/goals/DefaultGoal/BaseGoalScreen.tsx
+++ b/src/goals/DefaultGoal/BaseGoalScreen.tsx
@@ -1,22 +1,22 @@
import loadable from "@loadable/component";
-import React, { ReactElement, useEffect } from "react";
+import { ReactElement, useEffect } from "react";
import { setCurrentGoal } from "components/GoalTimeline/Redux/GoalActions";
import PageNotFound from "components/PageNotFound/component";
import DisplayProgress from "goals/DefaultGoal/DisplayProgress";
import Loading from "goals/DefaultGoal/Loading";
import { clearTree } from "goals/MergeDuplicates/Redux/MergeDupsActions";
-import ReviewDeferredDuplicates from "goals/ReviewDeferredDuplicates";
-import { clearReviewEntriesState } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
+import { clearReviewEntriesState } from "goals/ReviewEntries/Redux/ReviewEntriesActions";
import { StoreState } from "types";
import { Goal, GoalStatus, GoalType } from "types/goals";
import { useAppDispatch, useAppSelector } from "types/hooks";
const CharacterInventory = loadable(() => import("goals/CharacterInventory"));
const MergeDup = loadable(() => import("goals/MergeDuplicates"));
-const ReviewEntriesComponent = loadable(
- () => import("goals/ReviewEntries/ReviewEntriesComponent")
+const ReviewDeferredDups = loadable(
+ () => import("goals/ReviewDeferredDuplicates")
);
+const ReviewEntries = loadable(() => import("goals/ReviewEntries"));
function displayComponent(goal: Goal): ReactElement {
const isCompleted = goal.status === GoalStatus.Completed;
@@ -26,9 +26,9 @@ function displayComponent(goal: Goal): ReactElement {
case GoalType.MergeDups:
return ;
case GoalType.ReviewDeferredDups:
- return ;
+ return ;
case GoalType.ReviewEntries:
- return ;
+ return ;
default:
return ;
}
@@ -58,9 +58,9 @@ export function BaseGoalScreen(): ReactElement {
}, [dispatch]);
return (
-
+ <>
{goal.status !== GoalStatus.Completed && }
{displayComponent(goal)}
-
+ >
);
}
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions.ts b/src/goals/ReviewEntries/Redux/ReviewEntriesActions.ts
similarity index 97%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions.ts
rename to src/goals/ReviewEntries/Redux/ReviewEntriesActions.ts
index d3d854293d..abceaab552 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions.ts
+++ b/src/goals/ReviewEntries/Redux/ReviewEntriesActions.ts
@@ -7,11 +7,11 @@ import {
ReviewEntriesActionTypes,
ReviewUpdateWord,
ReviewUpdateWords,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
+} from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreStateDispatch } from "types/Redux/actions";
import { newNote, newSense } from "types/word";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReducer.ts b/src/goals/ReviewEntries/Redux/ReviewEntriesReducer.ts
similarity index 92%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReducer.ts
rename to src/goals/ReviewEntries/Redux/ReviewEntriesReducer.ts
index bbab90bdb6..1b2bbd52ba 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReducer.ts
+++ b/src/goals/ReviewEntries/Redux/ReviewEntriesReducer.ts
@@ -3,7 +3,7 @@ import {
ReviewEntriesAction,
ReviewEntriesActionTypes,
ReviewEntriesState,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
+} from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import { StoreAction, StoreActionTypes } from "rootActions";
export const reviewEntriesReducer = (
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes.ts b/src/goals/ReviewEntries/Redux/ReviewEntriesReduxTypes.ts
similarity index 96%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes.ts
rename to src/goals/ReviewEntries/Redux/ReviewEntriesReduxTypes.ts
index 567c813eee..0aa78d50c2 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes.ts
+++ b/src/goals/ReviewEntries/Redux/ReviewEntriesReduxTypes.ts
@@ -1,4 +1,4 @@
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
export enum ReviewEntriesActionTypes {
UpdateAllWords = "UPDATE_ALL_WORDS",
diff --git a/src/goals/ReviewEntries/ReviewEntries.ts b/src/goals/ReviewEntries/ReviewEntries.ts
deleted file mode 100644
index d51fefbfdd..0000000000
--- a/src/goals/ReviewEntries/ReviewEntries.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Goal, GoalName, GoalType } from "types/goals";
-
-export class ReviewEntries extends Goal {
- constructor() {
- super(GoalType.ReviewEntries, GoalName.ReviewEntries);
- }
-}
-
-export type EntryEdit = {
- newId: string;
- oldId: string;
-};
-
-export interface EntriesEdited {
- entryEdits: EntryEdit[];
-}
diff --git a/src/goals/ReviewEntries/ReviewEntriesCompleted.tsx b/src/goals/ReviewEntries/ReviewEntriesCompleted.tsx
new file mode 100644
index 0000000000..e179150888
--- /dev/null
+++ b/src/goals/ReviewEntries/ReviewEntriesCompleted.tsx
@@ -0,0 +1,117 @@
+import { ArrowRightAlt } from "@mui/icons-material";
+import { Button, Grid, Typography } from "@mui/material";
+import { ReactElement, useEffect, useState } from "react";
+import { useTranslation } from "react-i18next";
+import { useSelector } from "react-redux";
+
+import { getFrontierWords, getWord, updateWord } from "backend";
+import { CancelConfirmDialog } from "components/Dialogs";
+import {
+ EntriesEdited,
+ EntryEdit,
+} from "goals/ReviewEntries/ReviewEntriesTypes";
+import { StoreState } from "types";
+import theme from "types/theme";
+
+export default function ReviewEntriesCompleted(): ReactElement {
+ const changes = useSelector(
+ (state: StoreState) => state.goalsState.currentGoal.changes as EntriesEdited
+ );
+ const { t } = useTranslation();
+
+ return (
+ <>
+
+ {t("reviewEntries.title")}
+
+
+ {t("reviewEntries.completed.number")}
+ {changes.entryEdits?.length ?? 0}
+
+ {changes.entryEdits?.map((e) => )}
+ >
+ );
+}
+
+function EditedEntry(props: { edit: EntryEdit }): ReactElement {
+ return (
+
+ {props.edit.oldId}
+
+
+
+ {props.edit.newId}
+
+
+ );
+}
+
+interface UndoButtonProps {
+ edit: EntryEdit;
+ textId: string;
+ dialogId: string;
+ disabledId: string;
+}
+
+function UndoButton(props: UndoButtonProps): ReactElement {
+ const [isUndoEnabled, setUndoEnabled] = useState(false);
+ const [undoDialogOpen, setUndoDialogOpen] = useState(false);
+ const { t } = useTranslation();
+
+ useEffect(() => {
+ function checkFrontier(): void {
+ getFrontierWords().then((words) =>
+ setUndoEnabled(words.findIndex((w) => w.id === props.edit.newId) !== -1)
+ );
+ }
+ checkFrontier();
+ });
+
+ return isUndoEnabled ? (
+
+ <>
+
+ setUndoDialogOpen(false)}
+ handleConfirm={() =>
+ undoEdit(props.edit).then(() => setUndoDialogOpen(false))
+ }
+ buttonIdCancel="edit-undo-cancel"
+ buttonIdConfirm="edit-undo-confirm"
+ />
+ >
+
+ ) : (
+
+ <>
+
+ >
+
+ );
+}
+
+const undoEdit = async (edit: EntryEdit): Promise => {
+ const oldWord = await getWord(edit.oldId);
+ await updateWord({ ...oldWord, id: edit.newId });
+};
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/index.ts b/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/index.ts
deleted file mode 100644
index 930c959a6a..0000000000
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import DefinitionCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DefinitionCell";
-import DeleteCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DeleteCell";
-import DomainCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DomainCell";
-import FlagCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/FlagCell";
-import GlossCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/GlossCell";
-import NoteCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/NoteCell";
-import PartOfSpeechCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PartOfSpeechCell";
-import PronunciationsCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PronunciationsCell";
-import SenseCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/SenseCell";
-import VernacularCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/VernacularCell";
-
-export {
- DefinitionCell,
- DeleteCell,
- DomainCell,
- FlagCell,
- GlossCell,
- NoteCell,
- PartOfSpeechCell,
- PronunciationsCell,
- SenseCell,
- VernacularCell,
-};
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellColumns.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellColumns.tsx
similarity index 99%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellColumns.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellColumns.tsx
index c61d582a7d..21321d3dbc 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellColumns.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellColumns.tsx
@@ -14,12 +14,12 @@ import {
PronunciationsCell,
SenseCell,
VernacularCell,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents";
import {
ReviewEntriesSense,
ReviewEntriesWord,
ReviewEntriesWordField,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { compareFlags } from "utilities/wordUtilities";
enum SortStyle {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList.tsx
similarity index 100%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList.tsx
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DefinitionCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DefinitionCell.tsx
similarity index 97%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DefinitionCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DefinitionCell.tsx
index bade811c7c..f905a44d3b 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DefinitionCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DefinitionCell.tsx
@@ -5,10 +5,10 @@ import { useSelector } from "react-redux";
import { Definition, WritingSystem } from "api/models";
import Overlay from "components/Overlay";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
import AlignedList, {
SPACER,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
import { StoreState } from "types";
import { newDefinition } from "types/word";
import {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DeleteCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell.tsx
similarity index 93%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DeleteCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell.tsx
index b69f7e4320..eeb88118bf 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DeleteCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell.tsx
@@ -5,8 +5,8 @@ import { useTranslation } from "react-i18next";
import { deleteFrontierWord as deleteFromBackend } from "backend";
import { CancelConfirmDialog } from "components/Dialogs";
-import { updateAllWords } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+import { updateAllWords } from "goals/ReviewEntries/Redux/ReviewEntriesActions";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreState } from "types";
import { useAppDispatch, useAppSelector } from "types/hooks";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DomainCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DomainCell.tsx
similarity index 97%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DomainCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DomainCell.tsx
index b20de93704..b91cd78a55 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DomainCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/DomainCell.tsx
@@ -11,11 +11,11 @@ import Overlay from "components/Overlay";
import TreeView from "components/TreeView";
import AlignedList, {
SPACER,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreState } from "types";
import { newSemanticDomainForMongoDB } from "types/semanticDomain";
import { themeColors } from "types/theme";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/FlagCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/FlagCell.tsx
similarity index 95%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/FlagCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/FlagCell.tsx
index b93d65af6a..5b907d05fa 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/FlagCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/FlagCell.tsx
@@ -2,7 +2,7 @@ import { ReactElement } from "react";
import { Flag } from "api/models";
import FlagButton from "components/Buttons/FlagButton";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
interface FlagCellProps extends FieldParameterStandard {
editable?: boolean;
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/GlossCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/GlossCell.tsx
similarity index 96%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/GlossCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/GlossCell.tsx
index 72e66f37e6..2377aadee3 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/GlossCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/GlossCell.tsx
@@ -5,10 +5,10 @@ import { useSelector } from "react-redux";
import { Gloss, WritingSystem } from "api/models";
import Overlay from "components/Overlay";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
import AlignedList, {
SPACER,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
import { StoreState } from "types";
import { newGloss } from "types/word";
import {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/NoteCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/NoteCell.tsx
similarity index 95%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/NoteCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/NoteCell.tsx
index 8a91465be8..d2b5f1d213 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/NoteCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/NoteCell.tsx
@@ -2,7 +2,7 @@ import { TextField } from "@mui/material";
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
export default function NoteCell(props: FieldParameterStandard): ReactElement {
const { t } = useTranslation();
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PartOfSpeechCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PartOfSpeechCell.tsx
similarity index 85%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PartOfSpeechCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PartOfSpeechCell.tsx
index 50cd6d76dd..b82ec7a8f5 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PartOfSpeechCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PartOfSpeechCell.tsx
@@ -2,8 +2,8 @@ import { Grid } from "@mui/material";
import { ReactElement } from "react";
import { PartOfSpeechButton } from "components/Buttons";
-import AlignedList from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+import AlignedList from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
interface PartOfSpeechCellProps {
rowData: ReviewEntriesWord;
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PronunciationsCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PronunciationsCell.tsx
similarity index 95%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PronunciationsCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PronunciationsCell.tsx
index 4ae4d14d4a..001727e8fa 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PronunciationsCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/PronunciationsCell.tsx
@@ -5,7 +5,7 @@ import PronunciationsFrontend from "components/Pronunciations/PronunciationsFron
import {
deleteAudio,
uploadAudio,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
+} from "goals/ReviewEntries/Redux/ReviewEntriesActions";
import { useAppDispatch } from "types/hooks";
interface PronunciationsCellProps {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/SenseCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/SenseCell.tsx
similarity index 91%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/SenseCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/SenseCell.tsx
index 6415703314..2206554650 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/SenseCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/SenseCell.tsx
@@ -3,9 +3,9 @@ import { Chip, IconButton, Tooltip } from "@mui/material";
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
-import AlignedList from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
-import { ReviewEntriesSense } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
+import AlignedList from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
+import { ReviewEntriesSense } from "goals/ReviewEntries/ReviewEntriesTypes";
interface SenseCellProps extends FieldParameterStandard {
delete: (deleteIndex: string) => void;
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/VernacularCell.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/VernacularCell.tsx
similarity index 97%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/VernacularCell.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/VernacularCell.tsx
index 0ca5fff7d5..6e38dcfbb9 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/VernacularCell.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/VernacularCell.tsx
@@ -1,7 +1,7 @@
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
-import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
import { TextFieldWithFont } from "utilities/fontComponents";
interface VernacularCellProps extends FieldParameterStandard {
diff --git a/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/index.ts b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/index.ts
new file mode 100644
index 0000000000..ad76e1318e
--- /dev/null
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/index.ts
@@ -0,0 +1,23 @@
+import DefinitionCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DefinitionCell";
+import DeleteCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell";
+import DomainCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DomainCell";
+import FlagCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/FlagCell";
+import GlossCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/GlossCell";
+import NoteCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/NoteCell";
+import PartOfSpeechCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/PartOfSpeechCell";
+import PronunciationsCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/PronunciationsCell";
+import SenseCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/SenseCell";
+import VernacularCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/VernacularCell";
+
+export {
+ DefinitionCell,
+ DeleteCell,
+ DomainCell,
+ FlagCell,
+ GlossCell,
+ NoteCell,
+ PartOfSpeechCell,
+ PronunciationsCell,
+ SenseCell,
+ VernacularCell,
+};
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/AlignedList.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/AlignedList.test.tsx
similarity index 77%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/AlignedList.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/AlignedList.test.tsx
index f808edea63..bfc9a168d7 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/AlignedList.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/AlignedList.test.tsx
@@ -1,6 +1,6 @@
import renderer from "react-test-renderer";
-import AlignedList from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
+import AlignedList from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/AlignedList";
describe("AlignedList", () => {
it("renders without crashing", () => {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DefinitionCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DefinitionCell.test.tsx
similarity index 86%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DefinitionCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DefinitionCell.test.tsx
index d02bdb8df4..52531f8f74 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DefinitionCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DefinitionCell.test.tsx
@@ -4,8 +4,8 @@ import configureMockStore from "redux-mock-store";
import "tests/reactI18nextMock";
-import DefinitionCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DefinitionCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import DefinitionCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DefinitionCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
import { defaultWritingSystem } from "types/writingSystem";
// The multiline Input, TextField cause problems in the mock environment.
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DeleteCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DeleteCell.test.tsx
similarity index 69%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DeleteCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DeleteCell.test.tsx
index 9824eb6309..2cc3b02281 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DeleteCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DeleteCell.test.tsx
@@ -4,9 +4,9 @@ import configureMockStore from "redux-mock-store";
import "tests/reactI18nextMock";
-import DeleteCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DeleteCell";
-import { defaultState as reviewEntriesState } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import { defaultState as reviewEntriesState } from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
+import DeleteCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DeleteCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
const mockStore = configureMockStore()({ reviewEntriesState });
const mockWord = mockWords()[0];
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DomainCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DomainCell.test.tsx
similarity index 81%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DomainCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DomainCell.test.tsx
index a5aa75ed2f..9dc44ae1e0 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/DomainCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/DomainCell.test.tsx
@@ -4,8 +4,8 @@ import configureMockStore from "redux-mock-store";
import "tests/reactI18nextMock";
-import DomainCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/DomainCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import DomainCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/DomainCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
jest.mock("components/TreeView", () => "div");
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/FlagCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/FlagCell.test.tsx
similarity index 72%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/FlagCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/FlagCell.test.tsx
index 5663d9dc4d..69a52cd1d0 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/FlagCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/FlagCell.test.tsx
@@ -2,8 +2,8 @@ import renderer from "react-test-renderer";
import "tests/reactI18nextMock";
-import FlagCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/FlagCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import FlagCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/FlagCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
const mockWord = mockWords()[1];
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/GlossCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/GlossCell.test.tsx
similarity index 86%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/GlossCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/GlossCell.test.tsx
index 636296aa88..61069b279f 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/GlossCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/GlossCell.test.tsx
@@ -4,8 +4,8 @@ import configureMockStore from "redux-mock-store";
import "tests/reactI18nextMock";
-import GlossCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/GlossCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import GlossCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/GlossCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
import { defaultWritingSystem } from "types/writingSystem";
// The multiline Input, TextField cause problems in the mock environment.
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/NoteCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/NoteCell.test.tsx
similarity index 70%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/NoteCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/NoteCell.test.tsx
index 1a64a8e1ec..1eb657bc9f 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/NoteCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/NoteCell.test.tsx
@@ -2,8 +2,8 @@ import renderer from "react-test-renderer";
import "tests/reactI18nextMock";
-import NoteCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/NoteCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import NoteCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/NoteCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
// The multiline TextField causes problems in the mock environment.
jest.mock("@mui/material/TextField", () => "div");
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PartOfSpeechCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PartOfSpeechCell.test.tsx
similarity index 59%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PartOfSpeechCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PartOfSpeechCell.test.tsx
index 7eaf3d0b76..e267907195 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PartOfSpeechCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PartOfSpeechCell.test.tsx
@@ -2,8 +2,8 @@ import renderer from "react-test-renderer";
import "tests/reactI18nextMock";
-import PartOfSpeechCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PartOfSpeechCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import PartOfSpeechCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/PartOfSpeechCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
const mockWord = mockWords()[1];
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PronunciationsCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PronunciationsCell.test.tsx
similarity index 94%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PronunciationsCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PronunciationsCell.test.tsx
index e5cb3a1352..a5d4eb955d 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/PronunciationsCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/PronunciationsCell.test.tsx
@@ -8,7 +8,7 @@ import "tests/reactI18nextMock";
import AudioPlayer from "components/Pronunciations/AudioPlayer";
import AudioRecorder from "components/Pronunciations/AudioRecorder";
import { defaultState as pronunciationsState } from "components/Pronunciations/Redux/PronunciationsReduxTypes";
-import PronunciationsCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/PronunciationsCell";
+import PronunciationsCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/PronunciationsCell";
import theme from "types/theme";
// Mock the audio components
@@ -18,13 +18,10 @@ jest
jest.mock("components/Pronunciations/Recorder");
// Mock the store interactions
-jest.mock(
- "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions",
- () => ({
- deleteAudio: (...args: any[]) => mockDeleteAudio(...args),
- uploadAudio: (...args: any[]) => mockUploadAudio(...args),
- })
-);
+jest.mock("goals/ReviewEntries/Redux/ReviewEntriesActions", () => ({
+ deleteAudio: (...args: any[]) => mockDeleteAudio(...args),
+ uploadAudio: (...args: any[]) => mockUploadAudio(...args),
+}));
jest.mock("types/hooks", () => {
return {
...jest.requireActual("types/hooks"),
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/SenseCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/SenseCell.test.tsx
similarity index 67%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/SenseCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/SenseCell.test.tsx
index eff956e6f2..1244b93cc3 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/SenseCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/SenseCell.test.tsx
@@ -2,8 +2,8 @@ import renderer from "react-test-renderer";
import "tests/reactI18nextMock";
-import SenseCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/SenseCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import SenseCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/SenseCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
const mockWord = mockWords()[1];
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/VernacularCell.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/VernacularCell.test.tsx
similarity index 78%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/VernacularCell.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/VernacularCell.test.tsx
index 200844b6a9..71d0237853 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/CellComponents/tests/VernacularCell.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/CellComponents/tests/VernacularCell.test.tsx
@@ -2,8 +2,8 @@ import renderer from "react-test-renderer";
import "tests/reactI18nextMock";
-import VernacularCell from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/VernacularCell";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import VernacularCell from "goals/ReviewEntries/ReviewEntriesTable/CellComponents/VernacularCell";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
// The multiline TextField causes problems in the mock environment.
jest.mock("@mui/material/TextField", () => "div");
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/icons.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/icons.tsx
similarity index 100%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/icons.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/icons.tsx
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTable.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx
similarity index 96%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTable.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/index.tsx
index 674eed105a..0b30f3244c 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTable.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/index.tsx
@@ -7,9 +7,9 @@ import { useSelector } from "react-redux";
import columns, {
ColumnTitle,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
-import tableIcons from "goals/ReviewEntries/ReviewEntriesComponent/icons";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
+import tableIcons from "goals/ReviewEntries/ReviewEntriesTable/icons";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
import { StoreState } from "types";
interface ReviewEntriesTableProps {
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/CellColumns.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/tests/CellColumns.test.tsx
similarity index 98%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/tests/CellColumns.test.tsx
rename to src/goals/ReviewEntries/ReviewEntriesTable/tests/CellColumns.test.tsx
index 0816d1f440..7573933d0c 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/CellColumns.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/tests/CellColumns.test.tsx
@@ -3,11 +3,11 @@ import "tests/reactI18nextMock";
import { GramCatGroup, GrammaticalInfo } from "api/models";
import columns, {
ColumnTitle,
-} from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
+} from "goals/ReviewEntries/ReviewEntriesTable/CellColumns";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { newSemanticDomain } from "types/semanticDomain";
import { newDefinition, newFlag, newGloss } from "types/word";
import { Bcp47Code } from "types/writingSystem";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes.ts b/src/goals/ReviewEntries/ReviewEntriesTypes.ts
similarity index 88%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes.ts
rename to src/goals/ReviewEntries/ReviewEntriesTypes.ts
index 86e894766e..fdc31e17d9 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes.ts
+++ b/src/goals/ReviewEntries/ReviewEntriesTypes.ts
@@ -8,9 +8,25 @@ import {
Status,
Word,
} from "api/models";
+import { Goal, GoalName, GoalType } from "types/goals";
import { newSense, newWord } from "types/word";
import { cleanDefinitions, cleanGlosses } from "utilities/wordUtilities";
+export class ReviewEntries extends Goal {
+ constructor() {
+ super(GoalType.ReviewEntries, GoalName.ReviewEntries);
+ }
+}
+
+export type EntryEdit = {
+ newId: string;
+ oldId: string;
+};
+
+export interface EntriesEdited {
+ entryEdits: EntryEdit[];
+}
+
// These must match the ReviewEntriesWord fields for use in ReviewEntriesTable
export enum ReviewEntriesWordField {
Id = "id",
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/index.tsx b/src/goals/ReviewEntries/index.tsx
similarity index 51%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/index.tsx
rename to src/goals/ReviewEntries/index.tsx
index 44f234c71b..addb6b26e0 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/index.tsx
+++ b/src/goals/ReviewEntries/index.tsx
@@ -4,23 +4,32 @@ import { getFrontierWords } from "backend";
import {
updateAllWords,
updateFrontierWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
-import ReviewEntriesTable from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTable";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/Redux/ReviewEntriesActions";
+import ReviewEntriesCompleted from "goals/ReviewEntries/ReviewEntriesCompleted";
+import ReviewEntriesTable from "goals/ReviewEntries/ReviewEntriesTable";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
import { useAppDispatch } from "types/hooks";
-export default function ReviewEntriesComponent(): ReactElement {
+interface ReviewEntriesProps {
+ completed: boolean;
+}
+
+export default function ReviewEntries(props: ReviewEntriesProps): ReactElement {
const dispatch = useAppDispatch();
const [loaded, setLoaded] = useState(false);
useEffect(() => {
- getFrontierWords().then((frontier) => {
- dispatch(updateAllWords(frontier.map((w) => new ReviewEntriesWord(w))));
- setLoaded(true);
- });
- }, [dispatch]);
+ if (!props.completed) {
+ getFrontierWords().then((frontier) => {
+ dispatch(updateAllWords(frontier.map((w) => new ReviewEntriesWord(w))));
+ setLoaded(true);
+ });
+ }
+ }, [dispatch, props]);
- return loaded ? (
+ return props.completed ? (
+
+ ) : loaded ? (
dispatch(updateFrontierWord(newData, oldData))
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesActions.test.tsx b/src/goals/ReviewEntries/tests/ReviewEntriesActions.test.tsx
similarity index 98%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesActions.test.tsx
rename to src/goals/ReviewEntries/tests/ReviewEntriesActions.test.tsx
index 67cda6fb0c..bf62285273 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesActions.test.tsx
+++ b/src/goals/ReviewEntries/tests/ReviewEntriesActions.test.tsx
@@ -6,11 +6,11 @@ import {
getSenseError,
getSenseFromEditSense,
updateFrontierWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
+} from "goals/ReviewEntries/Redux/ReviewEntriesActions";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { newSemanticDomain } from "types/semanticDomain";
import { newFlag, newGloss, newNote, newSense, newWord } from "types/word";
import { Bcp47Code } from "types/writingSystem";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesReducer.test.tsx b/src/goals/ReviewEntries/tests/ReviewEntriesReducer.test.tsx
similarity index 84%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesReducer.test.tsx
rename to src/goals/ReviewEntries/tests/ReviewEntriesReducer.test.tsx
index 4b3ca74e49..b9873b3331 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/ReviewEntriesReducer.test.tsx
+++ b/src/goals/ReviewEntries/tests/ReviewEntriesReducer.test.tsx
@@ -1,13 +1,13 @@
-import { reviewEntriesReducer } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReducer";
+import { reviewEntriesReducer } from "goals/ReviewEntries/Redux/ReviewEntriesReducer";
import {
defaultState,
ReviewEntriesActionTypes,
-} from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
+} from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
-import mockWords from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
+import mockWords from "goals/ReviewEntries/tests/WordsMock";
import { newSemanticDomain } from "types/semanticDomain";
import { Bcp47Code } from "types/writingSystem";
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock.ts b/src/goals/ReviewEntries/tests/WordsMock.ts
similarity index 96%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock.ts
rename to src/goals/ReviewEntries/tests/WordsMock.ts
index c2a70a592c..01a2bfbca9 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock.ts
+++ b/src/goals/ReviewEntries/tests/WordsMock.ts
@@ -2,7 +2,7 @@ import { GramCatGroup, Sense, Word } from "api/models";
import {
ReviewEntriesSense,
ReviewEntriesWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
+} from "goals/ReviewEntries/ReviewEntriesTypes";
import { newSemanticDomain } from "types/semanticDomain";
import {
newDefinition,
diff --git a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/index.test.tsx b/src/goals/ReviewEntries/tests/index.test.tsx
similarity index 84%
rename from src/goals/ReviewEntries/ReviewEntriesComponent/tests/index.test.tsx
rename to src/goals/ReviewEntries/tests/index.test.tsx
index 298cf1ae63..7590959b91 100644
--- a/src/goals/ReviewEntries/ReviewEntriesComponent/tests/index.test.tsx
+++ b/src/goals/ReviewEntries/tests/index.test.tsx
@@ -5,12 +5,10 @@ import configureMockStore from "redux-mock-store";
import "tests/reactI18nextMock";
-import ReviewEntriesComponent from "goals/ReviewEntries/ReviewEntriesComponent";
-import * as actions from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesActions";
-import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
-import mockWords, {
- mockCreateWord,
-} from "goals/ReviewEntries/ReviewEntriesComponent/tests/WordsMock";
+import ReviewEntries from "goals/ReviewEntries";
+import * as actions from "goals/ReviewEntries/Redux/ReviewEntriesActions";
+import { ReviewEntriesWord } from "goals/ReviewEntries/ReviewEntriesTypes";
+import mockWords, { mockCreateWord } from "goals/ReviewEntries/tests/WordsMock";
import { defaultWritingSystem } from "types/writingSystem";
const mockGetFrontierWords = jest.fn();
@@ -42,6 +40,9 @@ jest.mock("backend", () => ({
// Mock the node module used by AudioRecorder.
jest.mock("components/Pronunciations/Recorder");
jest.mock("components/TreeView", () => "div");
+jest.mock("components/GoalTimeline/Redux/GoalActions", () => ({
+ addEntryEditToGoal: () => jest.fn(),
+}));
jest.mock("types/hooks", () => ({
useAppDispatch: () => jest.fn(),
}));
@@ -61,11 +62,7 @@ const state = {
reviewEntriesState: { words: mockReviewEntryWords },
treeViewState: {
open: false,
- currentDomain: {
- name: "domain",
- id: "number",
- subdomains: [],
- },
+ currentDomain: { id: "number", name: "domain", subdomains: [] },
},
};
const mockStore = configureMockStore()(state);
@@ -90,13 +87,13 @@ beforeEach(async () => {
await act(async () => {
create(
-
+
);
});
});
-describe("ReviewEntriesComponent", () => {
+describe("ReviewEntries", () => {
it("Initializes correctly", () => {
expect(updateAllWordsSpy).toHaveBeenCalled();
const wordIds = updateAllWordsSpy.mock.calls[0][0].map(
diff --git a/src/rootReducer.ts b/src/rootReducer.ts
index dabea8c886..ecb00dd737 100644
--- a/src/rootReducer.ts
+++ b/src/rootReducer.ts
@@ -9,7 +9,7 @@ import { pronunciationsReducer } from "components/Pronunciations/Redux/Pronuncia
import { treeViewReducer } from "components/TreeView/Redux/TreeViewReducer";
import { characterInventoryReducer } from "goals/CharacterInventory/Redux/CharacterInventoryReducer";
import { mergeDupStepReducer } from "goals/MergeDuplicates/Redux/MergeDupsReducer";
-import { reviewEntriesReducer } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReducer";
+import { reviewEntriesReducer } from "goals/ReviewEntries/Redux/ReviewEntriesReducer";
import { StoreState } from "types";
import { analyticsReducer } from "types/Redux/analytics";
diff --git a/src/types/goals.ts b/src/types/goals.ts
index 8935d38af6..c2981dec8d 100644
--- a/src/types/goals.ts
+++ b/src/types/goals.ts
@@ -11,7 +11,7 @@ import {
MergeStepData,
MergesCompleted,
} from "goals/MergeDuplicates/MergeDupsTypes";
-import { EntriesEdited } from "goals/ReviewEntries/ReviewEntries";
+import { EntriesEdited } from "goals/ReviewEntries/ReviewEntriesTypes";
import { newUser } from "types/user";
export type GoalData = CharInvData | MergeDupsData;
diff --git a/src/types/index.ts b/src/types/index.ts
index a82aa20a00..9d374323b7 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -6,7 +6,7 @@ import { PronunciationsState } from "components/Pronunciations/Redux/Pronunciati
import { TreeViewState } from "components/TreeView/Redux/TreeViewReduxTypes";
import { CharacterInventoryState } from "goals/CharacterInventory/Redux/CharacterInventoryReduxTypes";
import { MergeTreeState } from "goals/MergeDuplicates/Redux/MergeDupsReduxTypes";
-import { ReviewEntriesState } from "goals/ReviewEntries/ReviewEntriesComponent/Redux/ReviewEntriesReduxTypes";
+import { ReviewEntriesState } from "goals/ReviewEntries/Redux/ReviewEntriesReduxTypes";
import { AnalyticsState } from "types/Redux/analyticsReduxTypes";
import { GoalsState } from "types/goals";
diff --git a/src/utilities/goalUtilities.ts b/src/utilities/goalUtilities.ts
index 21f1be80ca..e5e3abf8b2 100644
--- a/src/utilities/goalUtilities.ts
+++ b/src/utilities/goalUtilities.ts
@@ -6,7 +6,7 @@ import {
MergeDups,
ReviewDeferredDups,
} from "goals/MergeDuplicates/MergeDupsTypes";
-import { ReviewEntries } from "goals/ReviewEntries/ReviewEntries";
+import { ReviewEntries } from "goals/ReviewEntries/ReviewEntriesTypes";
import { SpellCheckGloss } from "goals/SpellCheckGloss/SpellCheckGloss";
import { ValidateChars } from "goals/ValidateChars/ValidateChars";
import { ValidateStrWords } from "goals/ValidateStrWords/ValidateStrWords";