From 0ef90812acb800eb64777cc4545ed6ee95c82aa1 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Mon, 16 Dec 2024 17:05:49 -0500 Subject: [PATCH 1/4] Extract protected-reasons-text functions --- .../MergeDupsStep/MergeDragDrop/DropWord.tsx | 63 +-------- .../MergeDupsStep/SenseCardContent.tsx | 71 +--------- .../MergeDupsStep/protectReasonUtils.ts | 132 ++++++++++++++++++ 3 files changed, 138 insertions(+), 128 deletions(-) create mode 100644 src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts diff --git a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx index 2d80007ec7..f79b4c4a28 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx +++ b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx @@ -11,7 +11,7 @@ import { type ReactElement } from "react"; import { Droppable } from "react-beautiful-dnd"; import { useTranslation } from "react-i18next"; -import { type Flag, type ProtectReason, ReasonType } from "api/models"; +import { type Flag } from "api/models"; import { FlagButton, IconButtonWithTooltip, @@ -20,6 +20,7 @@ import { import MultilineTooltipTitle from "components/MultilineTooltipTitle"; import { AudioSummary } from "components/WordCard"; import DragSense from "goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DragSense"; +import { protectReasonsText } from "goals/MergeDuplicates/MergeDupsStep/protectReasonUtils"; import { type MergeTreeWord } from "goals/MergeDuplicates/MergeDupsTreeTypes"; import { flagWord, @@ -164,68 +165,10 @@ export function DropWordCardHeader(
); - const reasonText = (reason: ProtectReason): string => { - // Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftEntry entry) - switch (reason.type) { - case ReasonType.Annotations: - return t("mergeDups.protectReason.annotations"); - case ReasonType.Etymologies: - return t("mergeDups.protectReason.etymologies"); - case ReasonType.Field: - return t("mergeDups.protectReason.field", { val: reason.value }); - case ReasonType.NoteWithType: - return t("mergeDups.protectReason.noteWithType", { val: reason.value }); - case ReasonType.Notes: - return t("mergeDups.protectReason.notesWord"); - case ReasonType.Relations: - return t("mergeDups.protectReason.relations"); - case ReasonType.Trait: - return reason.value ?? "(unknown trait)"; - case ReasonType.TraitDialectLabels: - return t("mergeDups.protectReason.traitDialectLabels", { - val: reason.value, - }); - case ReasonType.TraitDoNotPublishIn: - return t("mergeDups.protectReason.traitDoNotPublishIn", { - val: reason.value, - }); - case ReasonType.TraitDoNotUseForParsing: - return t("mergeDups.protectReason.traitDoNotUseForParsing", { - val: reason.value, - }); - case ReasonType.TraitEntryType: - return t("mergeDups.protectReason.traitEntryType", { - val: reason.value, - }); - case ReasonType.TraitExcludeAsHeadword: - return t("mergeDups.protectReason.traitExcludeAsHeadword"); - case ReasonType.TraitMinorEntryCondition: - return t("mergeDups.protectReason.traitMinorEntryCondition", { - val: reason.value, - }); - case ReasonType.TraitMorphType: - return t("mergeDups.protectReason.traitMorphType", { - val: reason.value, - }); - case ReasonType.TraitPublishIn: - return t("mergeDups.protectReason.traitPublishIn", { - val: reason.value, - }); - case ReasonType.Variants: - return t("mergeDups.protectReason.variants"); - default: - throw new Error(); - } - }; - const tooltipTexts = [t("mergeDups.helpText.protectedWord")]; const reasons = words[props.wordId]?.protectReasons; if (reasons?.length) { - tooltipTexts.push( - t("mergeDups.helpText.protectedData", { - val: reasons.map(reasonText).join("; "), - }) - ); + tooltipTexts.push(protectReasonsText(t, reasons, [])); } tooltipTexts.push(t("mergeDups.helpText.protectedWordInfo")); diff --git a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx index 252e431053..7d402ca996 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx +++ b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx @@ -3,17 +3,12 @@ import { CardContent, IconButton } from "@mui/material"; import { type ReactElement } from "react"; import { useTranslation } from "react-i18next"; -import { - GramCatGroup, - type ProtectReason, - ReasonType, - type Sense, - Status, -} from "api/models"; +import { GramCatGroup, type Sense, Status } from "api/models"; import { IconButtonWithTooltip, PartOfSpeechButton } from "components/Buttons"; import MultilineTooltipTitle from "components/MultilineTooltipTitle"; import DomainChipsGrid from "components/WordCard/DomainChipsGrid"; import SenseCardText from "components/WordCard/SenseCardText"; +import { protectReasonsText } from "goals/MergeDuplicates/MergeDupsStep/protectReasonUtils"; import { combineSenses } from "goals/MergeDuplicates/Redux/reducerUtilities"; interface SenseCardContentProps { @@ -41,72 +36,12 @@ export default function SenseCardContent( a.id.localeCompare(b.id) ); - const reasonText = (reason: ProtectReason): string => { - // Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftSense sense) - switch (reason.type) { - case ReasonType.Annotations: - return t("mergeDups.protectReason.annotations"); - case ReasonType.Examples: - return t("mergeDups.protectReason.examples"); - case ReasonType.Field: - return t("mergeDups.protectReason.field", { val: reason.value }); - case ReasonType.GramInfoTrait: - return t("mergeDups.protectReason.gramInfoTrait", { - val: reason.value, - }); - case ReasonType.Illustrations: - return t("mergeDups.protectReason.illustrations"); - case ReasonType.Notes: - return t("mergeDups.protectReason.notesSense"); - case ReasonType.Relations: - return t("mergeDups.protectReason.relations"); - case ReasonType.Reversals: - return t("mergeDups.protectReason.reversal", { val: reason.value }); - case ReasonType.Subsenses: - return t("mergeDups.protectReason.subsenses"); - case ReasonType.Trait: - return reason.value ?? "(unknown trait)"; - case ReasonType.TraitAnthroCode: - return t("mergeDups.protectReason.traitAnthroCode", { - val: reason.value, - }); - case ReasonType.TraitDomainType: - return t("mergeDups.protectReason.traitDomainType", { - val: reason.value, - }); - case ReasonType.TraitDoNotPublishIn: - return t("mergeDups.protectReason.traitDoNotPublishIn", { - val: reason.value, - }); - case ReasonType.TraitPublishIn: - return t("mergeDups.protectReason.traitPublishIn", { - val: reason.value, - }); - case ReasonType.TraitSenseType: - return t("mergeDups.protectReason.traitSenseType", { - val: reason.value, - }); - case ReasonType.TraitStatus: - return t("mergeDups.protectReason.traitStatus", { val: reason.value }); - case ReasonType.TraitUsageType: - return t("mergeDups.protectReason.traitUsageType", { - val: reason.value, - }); - default: - throw new Error(); - } - }; - const protectedWarning = !props.sidebar && sense.accessibility === Status.Protected; const tooltipTexts = [t("mergeDups.helpText.protectedSense")]; const reasons = sense.protectReasons; if (reasons?.length) { - tooltipTexts.push( - t("mergeDups.helpText.protectedData", { - val: reasons.map(reasonText).join("; "), - }) - ); + tooltipTexts.push(protectReasonsText(t, [], reasons)); } tooltipTexts.push(t("mergeDups.helpText.protectedSenseInfo")); diff --git a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts new file mode 100644 index 0000000000..cd23f0286c --- /dev/null +++ b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts @@ -0,0 +1,132 @@ +import { TFunction } from "i18next"; + +import { ProtectReason, ReasonType } from "api/models"; + +const sep = "; "; + +export function protectReasonsText( + t: TFunction<"translation", undefined>, + wordReasons: ProtectReason[] = [], + senseReasons: ProtectReason[] = [] +): string { + const wordTexts = wordReasons.map((r) => wordReasonText(t, r)); + const senseTexts = senseReasons.map((r) => senseReasonText(t, r)); + const val = [...wordTexts, ...senseTexts].join(sep); + return t("mergeDups.helpText.protectedData", { val }); +} + +/** Cases match Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftSense sense) */ +function senseReasonText( + t: TFunction<"translation", undefined>, + reason: ProtectReason +): string { + switch (reason.type) { + case ReasonType.Annotations: + return t("mergeDups.protectReason.annotations"); + case ReasonType.Examples: + return t("mergeDups.protectReason.examples"); + case ReasonType.Field: + return t("mergeDups.protectReason.field", { val: reason.value }); + case ReasonType.GramInfoTrait: + return t("mergeDups.protectReason.gramInfoTrait", { + val: reason.value, + }); + case ReasonType.Illustrations: + return t("mergeDups.protectReason.illustrations"); + case ReasonType.Notes: + return t("mergeDups.protectReason.notesSense"); + case ReasonType.Relations: + return t("mergeDups.protectReason.relations"); + case ReasonType.Reversals: + return t("mergeDups.protectReason.reversal", { val: reason.value }); + case ReasonType.Subsenses: + return t("mergeDups.protectReason.subsenses"); + case ReasonType.Trait: + return reason.value ?? "(unknown trait)"; + case ReasonType.TraitAnthroCode: + return t("mergeDups.protectReason.traitAnthroCode", { + val: reason.value, + }); + case ReasonType.TraitDomainType: + return t("mergeDups.protectReason.traitDomainType", { + val: reason.value, + }); + case ReasonType.TraitDoNotPublishIn: + return t("mergeDups.protectReason.traitDoNotPublishIn", { + val: reason.value, + }); + case ReasonType.TraitPublishIn: + return t("mergeDups.protectReason.traitPublishIn", { + val: reason.value, + }); + case ReasonType.TraitSenseType: + return t("mergeDups.protectReason.traitSenseType", { + val: reason.value, + }); + case ReasonType.TraitStatus: + return t("mergeDups.protectReason.traitStatus", { val: reason.value }); + case ReasonType.TraitUsageType: + return t("mergeDups.protectReason.traitUsageType", { + val: reason.value, + }); + default: + throw new Error(); + } +} + +/** Cases match Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftEntry entry) */ +function wordReasonText( + t: TFunction<"translation", undefined>, + reason: ProtectReason +): string { + switch (reason.type) { + case ReasonType.Annotations: + return t("mergeDups.protectReason.annotations"); + case ReasonType.Etymologies: + return t("mergeDups.protectReason.etymologies"); + case ReasonType.Field: + return t("mergeDups.protectReason.field", { val: reason.value }); + case ReasonType.NoteWithType: + return t("mergeDups.protectReason.noteWithType", { val: reason.value }); + case ReasonType.Notes: + return t("mergeDups.protectReason.notesWord"); + case ReasonType.Relations: + return t("mergeDups.protectReason.relations"); + case ReasonType.Trait: + return reason.value ?? "(unknown trait)"; + case ReasonType.TraitDialectLabels: + return t("mergeDups.protectReason.traitDialectLabels", { + val: reason.value, + }); + case ReasonType.TraitDoNotPublishIn: + return t("mergeDups.protectReason.traitDoNotPublishIn", { + val: reason.value, + }); + case ReasonType.TraitDoNotUseForParsing: + return t("mergeDups.protectReason.traitDoNotUseForParsing", { + val: reason.value, + }); + case ReasonType.TraitEntryType: + return t("mergeDups.protectReason.traitEntryType", { + val: reason.value, + }); + case ReasonType.TraitExcludeAsHeadword: + return t("mergeDups.protectReason.traitExcludeAsHeadword"); + case ReasonType.TraitMinorEntryCondition: + return t("mergeDups.protectReason.traitMinorEntryCondition", { + val: reason.value, + }); + case ReasonType.TraitMorphType: + return t("mergeDups.protectReason.traitMorphType", { + val: reason.value, + }); + case ReasonType.TraitPublishIn: + return t("mergeDups.protectReason.traitPublishIn", { + val: reason.value, + }); + case ReasonType.Variants: + return t("mergeDups.protectReason.variants"); + default: + throw new Error(); + } +} From 7ba07f5f921473eda120ffa7d5348a37a43bf0dd Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 17 Dec 2024 11:48:13 -0500 Subject: [PATCH 2/4] Use object over order --- .../MergeDupsStep/MergeDragDrop/DropWord.tsx | 2 +- .../MergeDupsStep/SenseCardContent.tsx | 2 +- .../MergeDupsStep/protectReasonUtils.ts | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx index f79b4c4a28..c6eea5c812 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx +++ b/src/goals/MergeDuplicates/MergeDupsStep/MergeDragDrop/DropWord.tsx @@ -168,7 +168,7 @@ export function DropWordCardHeader( const tooltipTexts = [t("mergeDups.helpText.protectedWord")]; const reasons = words[props.wordId]?.protectReasons; if (reasons?.length) { - tooltipTexts.push(protectReasonsText(t, reasons, [])); + tooltipTexts.push(protectReasonsText(t, { word: reasons })); } tooltipTexts.push(t("mergeDups.helpText.protectedWordInfo")); diff --git a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx index 7d402ca996..ea72dcd0a3 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx +++ b/src/goals/MergeDuplicates/MergeDupsStep/SenseCardContent.tsx @@ -41,7 +41,7 @@ export default function SenseCardContent( const tooltipTexts = [t("mergeDups.helpText.protectedSense")]; const reasons = sense.protectReasons; if (reasons?.length) { - tooltipTexts.push(protectReasonsText(t, [], reasons)); + tooltipTexts.push(protectReasonsText(t, { sense: reasons })); } tooltipTexts.push(t("mergeDups.helpText.protectedSenseInfo")); diff --git a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts index cd23f0286c..8af3200388 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts +++ b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts @@ -4,13 +4,17 @@ import { ProtectReason, ReasonType } from "api/models"; const sep = "; "; +interface WordSenseReasons { + sense?: ProtectReason[]; + word?: ProtectReason[]; +} + export function protectReasonsText( t: TFunction<"translation", undefined>, - wordReasons: ProtectReason[] = [], - senseReasons: ProtectReason[] = [] + reasons: WordSenseReasons ): string { - const wordTexts = wordReasons.map((r) => wordReasonText(t, r)); - const senseTexts = senseReasons.map((r) => senseReasonText(t, r)); + const wordTexts = reasons.word?.map((r) => wordReasonText(t, r)) ?? []; + const senseTexts = reasons.sense?.map((r) => senseReasonText(t, r)) ?? []; const val = [...wordTexts, ...senseTexts].join(sep); return t("mergeDups.helpText.protectedData", { val }); } From f48e1eba6d8c28e396fa299f6439031d8f7b7f8e Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 17 Dec 2024 11:52:48 -0500 Subject: [PATCH 3/4] Don't specify default type arguments --- .../MergeDupsStep/protectReasonUtils.ts | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts index 8af3200388..f14340b0b3 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts +++ b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts @@ -10,20 +10,17 @@ interface WordSenseReasons { } export function protectReasonsText( - t: TFunction<"translation", undefined>, + t: TFunction, reasons: WordSenseReasons ): string { - const wordTexts = reasons.word?.map((r) => wordReasonText(t, r)) ?? []; - const senseTexts = reasons.sense?.map((r) => senseReasonText(t, r)) ?? []; - const val = [...wordTexts, ...senseTexts].join(sep); - return t("mergeDups.helpText.protectedData", { val }); + const wordTexts = reasons.word?.map((r) => wordReasonText(t, r)); + const senseTexts = reasons.sense?.map((r) => senseReasonText(t, r)); + const allTexts = [...(wordTexts ?? []), ...(senseTexts ?? [])]; + return t("mergeDups.helpText.protectedData", { val: allTexts.join(sep) }); } /** Cases match Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftSense sense) */ -function senseReasonText( - t: TFunction<"translation", undefined>, - reason: ProtectReason -): string { +function senseReasonText(t: TFunction, reason: ProtectReason): string { switch (reason.type) { case ReasonType.Annotations: return t("mergeDups.protectReason.annotations"); @@ -79,10 +76,7 @@ function senseReasonText( } /** Cases match Backend/Helper/LiftHelper.cs > GetProtectedReasons(LiftEntry entry) */ -function wordReasonText( - t: TFunction<"translation", undefined>, - reason: ProtectReason -): string { +function wordReasonText(t: TFunction, reason: ProtectReason): string { switch (reason.type) { case ReasonType.Annotations: return t("mergeDups.protectReason.annotations"); From 6bede96f77dcfb8ec5d11b919e6c3016c0e3e3c6 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 17 Dec 2024 11:54:04 -0500 Subject: [PATCH 4/4] Specify type imports --- src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts index f14340b0b3..88543aa133 100644 --- a/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts +++ b/src/goals/MergeDuplicates/MergeDupsStep/protectReasonUtils.ts @@ -1,6 +1,6 @@ -import { TFunction } from "i18next"; +import { type TFunction } from "i18next"; -import { ProtectReason, ReasonType } from "api/models"; +import { type ProtectReason, ReasonType } from "api/models"; const sep = "; ";