Skip to content

Commit

Permalink
[DataEntryTable] Distinguish between new and updated words (#3307)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Aug 21, 2024
1 parent 559a2de commit 097f4af
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
24 changes: 15 additions & 9 deletions src/components/DataEntry/DataEntryTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ interface SenseSwitch {
}

export interface WordAccess {
word: Word;
isNew: boolean;
senseGuid: string;
word: Word;
}

enum DefunctStatus {
Expand Down Expand Up @@ -335,7 +336,7 @@ export default function DataEntryTable(
const recentWords = [...prevState.recentWords];
word.senses.forEach((s) => {
if (s.semanticDomains.some((dom) => dom.id === domId)) {
recentWords.push({ word, senseGuid: s.guid });
recentWords.push({ isNew: false, senseGuid: s.guid, word });
}
});
return { ...prevState, recentWords };
Expand All @@ -358,6 +359,7 @@ export default function DataEntryTable(
if (replaceIndex > -1) {
deleteCount = 1;
insertIndex = replaceIndex;
wordAccess.isNew = recentWords[replaceIndex].isNew;
}

if (insertIndex > -1 && insertIndex < recentWords.length) {
Expand Down Expand Up @@ -392,7 +394,7 @@ export default function DataEntryTable(
const replaceInDisplay = (oldId: string, word: Word): void => {
setState((prevState) => {
const recentWords = prevState.recentWords.map((a) =>
a.word.id === oldId ? { word, senseGuid: a.senseGuid } : a
a.word.id === oldId ? { ...a, word } : a
);
return { ...prevState, isFetchingFrontier: true, recentWords };
});
Expand Down Expand Up @@ -738,7 +740,10 @@ export default function DataEntryTable(
if (wordId !== word.id) {
word = await backend.getWord(wordId);
}
addToDisplay({ word, senseGuid: word.senses[0].guid }, insertIndex);
addToDisplay(
{ isNew: true, senseGuid: word.senses[0].guid, word },
insertIndex
);
},
[addAudiosToBackend, addDuplicateWord]
);
Expand All @@ -754,7 +759,7 @@ export default function DataEntryTable(
const wordId = await addAudiosToBackend(word.id, audio);
word = await backend.getWord(wordId);
}
addToDisplay({ word, senseGuid });
addToDisplay({ isNew: false, senseGuid, word });
};

/** Reset the entry table. If there is an un-submitted word then submit it. */
Expand Down Expand Up @@ -880,7 +885,7 @@ export default function DataEntryTable(
/** Retract a recent entry. */
const undoRecentEntry = useCallback(
async (eIndex: number): Promise<void> => {
const { word, senseGuid } = state.recentWords[eIndex];
const { isNew, senseGuid, word } = state.recentWords[eIndex];
const sIndex = word.senses.findIndex((s) => s.guid === senseGuid);
if (sIndex === -1) {
throw new Error("Entry does not have specified sense.");
Expand All @@ -890,8 +895,9 @@ export default function DataEntryTable(
const senses = [...word.senses];
const oldSense = senses[sIndex];
const oldDoms = oldSense.semanticDomains;
if (oldDoms.length > 1) {
// If there is more than one semantic domain in this sense, only remove the domain.
if (oldDoms.length > 1 || !isNew) {
// If there is more than one domain in this sense or the entry isn't new,
// only remove the domain.
const doms = oldDoms.filter((d) => d.id !== props.semanticDomain.id);
const newSense: Sense = { ...oldSense, semanticDomains: doms };
senses.splice(sIndex, 1, newSense);
Expand All @@ -901,7 +907,7 @@ export default function DataEntryTable(
senses.splice(sIndex, 1);
await updateWordInBackend({ ...word, senses });
} else {
// Since this is the only sense, delete the word.
// Since this is the only sense in a new word, delete the word.
await backend.deleteFrontierWord(word.id);
}
},
Expand Down
20 changes: 16 additions & 4 deletions src/components/DataEntry/DataEntryTable/tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,23 @@ describe("DataEntryTable", () => {

describe("updateEntryGloss", () => {
it("throws error when entry doesn't have sense with specified guid", () => {
const entry: WordAccess = { word: newWord(), senseGuid: "gibberish" };
const entry: WordAccess = {
isNew: true,
senseGuid: "gibberish",
word: newWord(),
};
expect(() => updateEntryGloss(entry, "def", "semDomId", "en")).toThrow();
});

it("directly updates a sense with no other semantic domains", () => {
const senseIndex = 1;
const sense = mockMultiWord.senses[senseIndex];
sense.semanticDomains = [mockSemDom];
const entry: WordAccess = { word: mockMultiWord, senseGuid: sense.guid };
const entry: WordAccess = {
isNew: false,
senseGuid: sense.guid,
word: mockMultiWord,
};
const def = "newGlossDef";

const expectedGloss: Gloss = { ...sense.glosses[0], def };
Expand All @@ -271,7 +279,11 @@ describe("DataEntryTable", () => {
const targetGloss = newGloss("target language", "tl");
sense.glosses = [...sense.glosses, targetGloss];
sense.semanticDomains = [mockSemDom];
const entry: WordAccess = { word: mockMultiWord, senseGuid: sense.guid };
const entry: WordAccess = {
isNew: false,
senseGuid: sense.guid,
word: mockMultiWord,
};
const def = "newGlossDef";

const expectedGloss: Gloss = { ...targetGloss, def };
Expand All @@ -291,7 +303,7 @@ describe("DataEntryTable", () => {
const sense = word.senses[0];
const otherDomain: SemanticDomain = { ...mockSemDom, id: "otherId" };
sense.semanticDomains = [otherDomain, mockSemDom];
const entry: WordAccess = { word, senseGuid: sense.guid };
const entry: WordAccess = { isNew: false, senseGuid: sense.guid, word };
const def = "newGlossDef";

const oldSense: Sense = { ...sense, semanticDomains: [otherDomain] };
Expand Down

0 comments on commit 097f4af

Please sign in to comment.