diff --git a/src/components/WordCard/SenseCard.tsx b/src/components/WordCard/SenseCard.tsx
index c1c34806a7..91de0b4f90 100644
--- a/src/components/WordCard/SenseCard.tsx
+++ b/src/components/WordCard/SenseCard.tsx
@@ -17,7 +17,6 @@ export enum SenseCardLabel {
interface SenseCardProps {
bgColor?: string;
- languages?: string[];
minimal?: boolean;
provenance?: boolean;
sense: Sense;
@@ -43,11 +42,7 @@ export default function SenseCard(props: SenseCardProps): ReactElement {
{/* Glosses and (if any) definitions */}
-
+
{/* Semantic domains */}
diff --git a/src/components/WordCard/SenseCardText.tsx b/src/components/WordCard/SenseCardText.tsx
index 31c25587ca..59697240d9 100644
--- a/src/components/WordCard/SenseCardText.tsx
+++ b/src/components/WordCard/SenseCardText.tsx
@@ -8,8 +8,11 @@ import {
Typography,
} from "@mui/material";
import { ReactElement } from "react";
+import { shallowEqual } from "react-redux";
import { Sense } from "api/models";
+import { useAppSelector } from "rootRedux/hooks";
+import { type StoreState } from "rootRedux/types";
import { TypographyWithFont } from "utilities/fontComponents";
interface SenseInLanguage {
@@ -36,25 +39,26 @@ function getSenseInLanguage(
function getSenseInLanguages(
sense: Sense,
- languages?: string[]
+ languages: string[]
): SenseInLanguage[] {
- if (!languages) {
- languages = sense.glosses.map((g) => g.language);
- languages.push(...sense.definitions.map((d) => d.language));
- languages = [...new Set(languages)];
- }
return languages.map((l) => getSenseInLanguage(sense, l));
}
interface SenseCardTextProps {
sense: Sense;
hideDefs?: boolean;
- languages?: string[];
}
// Show glosses and (if not hideDefs) definitions.
export default function SenseCardText(props: SenseCardTextProps): ReactElement {
- const senseTextInLangs = getSenseInLanguages(props.sense, props.languages);
+ const analysisLangs = useAppSelector(
+ (state: StoreState) =>
+ state.currentProjectState.project.analysisWritingSystems.map(
+ (ws) => ws.bcp47
+ ),
+ shallowEqual
+ );
+ const senseTextInLangs = getSenseInLanguages(props.sense, analysisLangs);
return (
diff --git a/src/components/WordCard/SensesTextSummary.tsx b/src/components/WordCard/SensesTextSummary.tsx
index 8d00300185..394e01cf62 100644
--- a/src/components/WordCard/SensesTextSummary.tsx
+++ b/src/components/WordCard/SensesTextSummary.tsx
@@ -1,6 +1,9 @@
import { type ReactElement } from "react";
+import { shallowEqual } from "react-redux";
import { type Sense } from "api/models";
+import { useAppSelector } from "rootRedux/hooks";
+import { type StoreState } from "rootRedux/types";
import { TypographyWithFont } from "utilities/fontComponents";
interface SensesTextSummaryProp {
@@ -16,16 +19,49 @@ export default function SensesTextSummary(
const interSenseSep = " | ";
const intraSenseSep = "; ";
+ const analysisLangs = useAppSelector(
+ (state: StoreState) =>
+ state.currentProjectState.project.analysisWritingSystems.map(
+ (ws) => ws.bcp47
+ ),
+ shallowEqual
+ );
+
const typographies: ReactElement[] = [];
props.senses.forEach((sense) => {
let texts: string[];
+ let lang: string | undefined;
switch (props.definitionsOrGlosses) {
case "definitions":
- texts = sense.definitions.map((d) => d.text.trim());
+ if (analysisLangs.length) {
+ texts = analysisLangs.flatMap((l) =>
+ sense.definitions
+ .filter((d) => d.language === l)
+ .map((d) => d.text.trim())
+ );
+ lang = analysisLangs.find((l) =>
+ sense.definitions.some((d) => d.language === l && d.text.trim())
+ );
+ } else {
+ texts = sense.definitions.map((d) => d.text.trim());
+ lang = sense.definitions.find((d) => d.text.trim())?.language;
+ }
break;
case "glosses":
- texts = sense.glosses.map((g) => g.def.trim());
+ if (analysisLangs.length) {
+ texts = analysisLangs.flatMap((l) =>
+ sense.glosses
+ .filter((g) => g.language === l)
+ .map((g) => g.def.trim())
+ );
+ lang = analysisLangs.find((l) =>
+ sense.glosses.some((g) => g.language === l && g.def.trim())
+ );
+ } else {
+ texts = sense.glosses.map((g) => g.def.trim());
+ lang = sense.glosses.find((g) => g.def.trim())?.language;
+ }
break;
}
let text = texts.filter((t) => t).join(intraSenseSep);
@@ -49,16 +85,6 @@ export default function SensesTextSummary(
);
}
- // Use the analysis language of the first non-empty definition/gloss, if any.
- let lang: string | undefined;
- switch (props.definitionsOrGlosses) {
- case "definitions":
- lang = sense.definitions.find((d) => d.text.trim())?.language;
- break;
- case "glosses":
- lang = sense.glosses.find((g) => g.def.trim())?.language;
- break;
- }
typographies.push(
{senses.map((s) => (
-
+
))}
) : (
diff --git a/src/goals/CharacterInventory/tests/CharInvCompleted.test.tsx b/src/goals/CharacterInventory/tests/CharInvCompleted.test.tsx
index 4926555254..75116cd658 100644
--- a/src/goals/CharacterInventory/tests/CharInvCompleted.test.tsx
+++ b/src/goals/CharacterInventory/tests/CharInvCompleted.test.tsx
@@ -13,8 +13,7 @@ import {
type FindAndReplaceChange,
defaultCharInvChanges,
} from "goals/CharacterInventory/CharacterInventoryTypes";
-import { defaultState } from "goals/Redux/GoalReduxTypes";
-import { type StoreState } from "rootRedux/types";
+import { defaultState, type StoreState } from "rootRedux/types";
import { newWord as mockWord } from "types/word";
jest.mock("backend", () => ({
@@ -38,10 +37,11 @@ const mockWordChanges: FindAndReplaceChange = {
replace: "q",
words: { [mockWordKeys[0]]: "newA", [mockWordKeys[1]]: "newB" },
};
-const mockState = (changes?: CharInvChanges): Partial => ({
+const mockState = (changes?: CharInvChanges): StoreState => ({
+ ...defaultState,
goalsState: {
- ...defaultState,
- currentGoal: { ...defaultState.currentGoal, changes },
+ ...defaultState.goalsState,
+ currentGoal: { ...defaultState.goalsState.currentGoal, changes },
},
});
diff --git a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DragSense.tsx b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DragSense.tsx
index 15f0eef8af..3cd3353aaa 100644
--- a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DragSense.tsx
+++ b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DragSense.tsx
@@ -1,6 +1,7 @@
import { Draggable } from "@hello-pangea/dnd";
import { Card } from "@mui/material";
import { type ReactElement, useCallback, useEffect, useState } from "react";
+import { shallowEqual } from "react-redux";
import { trashId } from "goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/MergeDragDropTypes";
import SenseCardContent from "goals/MergeDuplicates/MergeDupsStep/SenseCardContent";
@@ -20,27 +21,8 @@ interface DragSenseProps {
senseRef: MergeTreeReference;
}
-function arraysEqual(arr1: T[], arr2: T[]): boolean {
- if (arr1.length !== arr2.length) {
- return false;
- }
- for (let i = 0; i < arr1.length; i++) {
- if (arr1[i] !== arr2[i]) {
- return false;
- }
- }
- return true;
-}
-
export default function DragSense(props: DragSenseProps): ReactElement {
const [duplicateCount, setDuplicateCount] = useState(1);
- const analysisLangs = useAppSelector(
- (state: StoreState) =>
- state.currentProjectState.project.analysisWritingSystems.map(
- (ws) => ws.bcp47
- ),
- arraysEqual
- );
const dispatch = useAppDispatch();
const overrideProtection = useAppSelector(
(state: StoreState) => state.mergeDuplicateGoal.overrideProtection
@@ -78,7 +60,7 @@ export default function DragSense(props: DragSenseProps): ReactElement {
if (
isInSidebar &&
- !arraysEqual(
+ !shallowEqual(
sidebar.mergeSenses.map((m) => m.sense.guid),
props.mergeSenses.map((m) => m.sense.guid)
)
@@ -122,7 +104,6 @@ export default function DragSense(props: DragSenseProps): ReactElement {
>
s.sense)}
- languages={analysisLangs}
toggleFunction={toggleSidebar}
/>
diff --git a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx
index 926762afc2..c102dbfc62 100644
--- a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx
+++ b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx
@@ -12,7 +12,6 @@ import { combineSenses } from "goals/MergeDuplicates/Redux/reducerUtilities";
interface SenseCardContentProps {
senses: Sense[];
isCompleted?: boolean;
- languages?: string[];
sidebar?: boolean;
toggleFunction?: () => void;
}
@@ -73,7 +72,7 @@ export default function SenseCardContent(
)}
{/* List glosses and (if any) definitions. */}
-
+
{/* List semantic domains. */}
diff --git a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditSensesCardContent.test.tsx b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditSensesCardContent.test.tsx
index 32bb48bca4..a3337d728a 100644
--- a/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditSensesCardContent.test.tsx
+++ b/src/goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/tests/EditSensesCardContent.test.tsx
@@ -1,11 +1,14 @@
import "@testing-library/jest-dom";
import { act, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
+import { Provider } from "react-redux";
+import configureMockStore from "redux-mock-store";
import { GramCatGroup, Sense, Status } from "api/models";
import EditSensesCardContent, {
EditSensesId,
} from "goals/ReviewEntries/ReviewEntriesTable/Cells/EditCell/EditSensesCardContent";
+import { defaultState } from "rootRedux/types";
import { newSemanticDomain } from "types/semanticDomain";
import { newDefinition, newSense } from "types/word";
@@ -48,14 +51,16 @@ const mockSenses = (): Sense[] => [
const renderEditSensesCardContent = async (showSenses = true): Promise =>
await act(async () => {
render(
- mockMoveSense(from, to)}
- newSenses={mockSenses()}
- oldSenses={mockSenses()}
- showSenses={showSenses}
- toggleSenseDeleted={mockToggleSenseDeleted}
- updateOrAddSense={mockUpdateOrAddSense}
- />
+
+ mockMoveSense(from, to)}
+ newSenses={mockSenses()}
+ oldSenses={mockSenses()}
+ showSenses={showSenses}
+ toggleSenseDeleted={mockToggleSenseDeleted}
+ updateOrAddSense={mockUpdateOrAddSense}
+ />
+
);
});