Skip to content

Commit

Permalink
Disable GlossCell, DefinitionCell when sense being deleted (#2575)
Browse files Browse the repository at this point in the history
Also, finish work in DefinitionCell to match updates to GlossCell from #2493.
  • Loading branch information
imnasnainaec authored Sep 18, 2023
1 parent 4a1f0fc commit 7947492
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 102 deletions.
18 changes: 18 additions & 0 deletions src/components/Overlay/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ReactElement, ReactNode } from "react";

interface OverlayProps {
children?: ReactNode;
on?: boolean;
}

export default function Overlay(props: OverlayProps): ReactElement {
return (
<div
style={
props.on ? { backgroundColor: "white", opacity: 0.4, zIndex: 9 } : {}
}
>
{props.children}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { Input } from "@mui/material";
import { Typography } from "@mui/material";
import { ReactElement } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";

import { Definition } from "api/models";
import { Definition, WritingSystem } from "api/models";
import Overlay from "components/Overlay";
import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
import AlignedList, {
SPACER,
} from "goals/ReviewEntries/ReviewEntriesComponent/CellComponents/AlignedList";
import { ReviewEntriesSense } from "goals/ReviewEntries/ReviewEntriesComponent/ReviewEntriesTypes";
import { StoreState } from "types";
import { themeColors } from "types/theme";
import { newDefinition } from "types/word";
import { TextFieldWithFont } from "utilities/fontComponents";
import {
TextFieldWithFont,
TypographyWithFont,
} from "utilities/fontComponents";

interface DefinitionCellProps extends FieldParameterStandard {
editable?: boolean;
Expand All @@ -24,20 +26,19 @@ export default function DefinitionCell(
): ReactElement {
const analysisLang = useSelector(
(state: StoreState) =>
state.currentProjectState.project.analysisWritingSystems[0].bcp47
state.currentProjectState.project.analysisWritingSystems[0]
);
const { t } = useTranslation();

return (
<AlignedList
listId={`senses${props.rowData.id}`}
contents={props.rowData.senses.map((sense, index) =>
props.editable ? (
contents={props.rowData.senses.map((sense, index) => (
<Overlay key={index} on={sense.deleted}>
<DefinitionList
definitions={sense.definitions}
defaultLang={analysisLang}
keyPrefix={`row-${props.rowData.id}-definition`}
key={`row-${props.rowData.id}-definition`}
definitions={sense.definitions}
editable={props.editable && !sense.deleted}
idPrefix={`row-${props.rowData.id}-definition`}
onChange={(definitions) =>
props.onRowDataChange &&
props.onRowDataChange({
Expand All @@ -53,54 +54,59 @@ export default function DefinitionCell(
})
}
/>
) : (
<Input
fullWidth
key={`definitions${props.rowData.id}`}
value={ReviewEntriesSense.definitionString(props.value[index])}
placeholder={t("reviewEntries.noDefinition")}
disabled={sense.deleted}
readOnly
disableUnderline
multiline
style={
props.sortingByThis && index === 0
? { backgroundColor: themeColors.highlight }
: {}
}
/>
)
)}
</Overlay>
))}
bottomCell={props.editable ? SPACER : undefined}
/>
);
}

interface DefinitionListProps {
defaultLang: WritingSystem;
definitions: Definition[];
defaultLang: string;
keyPrefix: string;
editable?: boolean;
idPrefix: string;
onChange: (definitions: Definition[]) => void;
}

function DefinitionList(props: DefinitionListProps): ReactElement {
const langs = props.definitions.map((g) => g.language);
const definitions = langs.includes(props.defaultLang)
const { t } = useTranslation();

if (!props.editable) {
if (!props.definitions.find((d) => d.text)) {
return <Typography>{t("reviewEntries.noDefinition")}</Typography>;
}
return (
<>
{props.definitions
.filter((d) => d.text)
.map((d, i) => (
<TypographyWithFont analysis key={i} lang={d.language}>
{d.text}
</TypographyWithFont>
))}
</>
);
}

const definitions = props.definitions.find(
(d) => d.language === props.defaultLang.bcp47
)
? props.definitions
: [...props.definitions, newDefinition("", props.defaultLang)];
: [...props.definitions, newDefinition("", props.defaultLang.bcp47)];

return (
<>
{definitions.map((g, i) => (
{definitions.map((d, i) => (
<DefinitionField
definition={g}
key={`${props.keyPrefix}-${i}`}
textFieldId={`${props.keyPrefix}-${i}-text`}
definition={d}
key={i}
onChange={(definition: Definition) => {
const updatedDefinitions = [...definitions];
updatedDefinitions.splice(i, 1, definition);
props.onChange(updatedDefinitions);
}}
textFieldId={`${props.idPrefix}-${i}-text`}
/>
))}
</>
Expand All @@ -125,10 +131,9 @@ function DefinitionField(props: DefinitionFieldProps): ReactElement {
value={props.definition.text}
error={props.definition.text.length === 0}
onChange={(event) =>
props.onChange({
language: props.definition.language,
text: event.target.value,
})
props.onChange(
newDefinition(event.target.value, props.definition.language)
)
}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Add } from "@mui/icons-material";
import { Chip, Dialog, Grid, IconButton } from "@mui/material";
import React, { ReactElement, useState } from "react";
import { ReactElement, useState } from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { toast } from "react-toastify";

import { SemanticDomain } from "api/models";
import { getCurrentUser } from "backend/localStorage";
import Overlay from "components/Overlay";
import TreeView from "components/TreeView";
import AlignedList, {
SPACER,
Expand Down Expand Up @@ -96,51 +97,53 @@ export default function DomainCell(props: DomainCellProps): ReactElement {
const { t } = useTranslation();

return (
<React.Fragment>
<>
<AlignedList
key={`domainCell:${props.rowData.id}`}
listId={`domains${props.rowData.id}`}
contents={props.rowData.senses.map((sense, senseIndex) => (
<Grid container direction="row" spacing={2} key={senseIndex}>
{sense.domains.length > 0 ? (
sense.domains.map((domain, domainIndex) => (
<Grid
item
key={`${domain.name}::${props.rowData.id}:${sense.guid}`}
>
<Overlay key={senseIndex} on={sense.deleted}>
<Grid container direction="row" spacing={2}>
{sense.domains.length > 0 ? (
sense.domains.map((domain, domainIndex) => (
<Grid
item
key={`${domain.name}::${props.rowData.id}:${sense.guid}`}
>
<Chip
color={sense.deleted ? "secondary" : "default"}
style={getChipStyle(senseIndex, domainIndex)}
label={`${domain.id}: ${domain.name}`}
onDelete={
props.editDomains && !sense.deleted
? () => deleteDomain(domain, sense)
: undefined
}
id={`sense-${sense.guid}-domain-${domainIndex}`}
/>
</Grid>
))
) : (
<Grid item xs key={`noDomain${sense.guid}`}>
<Chip
color={sense.deleted ? "secondary" : "default"}
style={getChipStyle(senseIndex, domainIndex)}
label={`${domain.id}: ${domain.name}`}
onDelete={
props.editDomains && !sense.deleted
? () => deleteDomain(domain, sense)
: undefined
}
id={`sense-${sense.guid}-domain-${domainIndex}`}
label={t("reviewEntries.noDomain")}
color={props.sortingByThis ? "default" : "secondary"}
style={getChipStyle(senseIndex, 0)}
/>
</Grid>
))
) : (
<Grid item xs key={`noDomain${sense.guid}`}>
<Chip
label={t("reviewEntries.noDomain")}
color={props.sortingByThis ? "default" : "secondary"}
style={getChipStyle(senseIndex, 0)}
/>
</Grid>
)}
{props.editDomains && !sense.deleted && (
<IconButton
key={`buttonFor${sense.guid}`}
onClick={() => prepAddDomain(sense)}
id={`sense-${sense.guid}-domain-add`}
size="large"
>
<Add />
</IconButton>
)}
</Grid>
)}
{props.editDomains && !sense.deleted && (
<IconButton
key={`buttonFor${sense.guid}`}
onClick={() => prepAddDomain(sense)}
id={`sense-${sense.guid}-domain-add`}
size="large"
>
<Add />
</IconButton>
)}
</Grid>
</Overlay>
))}
bottomCell={props.editDomains ? SPACER : undefined}
/>
Expand All @@ -150,6 +153,6 @@ export default function DomainCell(props: DomainCellProps): ReactElement {
returnControlToCaller={addDomain}
/>
</Dialog>
</React.Fragment>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";

import { Gloss, WritingSystem } from "api/models";
import Overlay from "components/Overlay";
import { FieldParameterStandard } from "goals/ReviewEntries/ReviewEntriesComponent/CellColumns";
import AlignedList, {
SPACER,
Expand All @@ -30,24 +31,25 @@ export default function GlossCell(props: GlossCellProps): ReactElement {
<AlignedList
listId={`senses${props.rowData.id}`}
contents={props.rowData.senses.map((sense, index) => (
<GlossList
defaultLang={analysisLang}
editable={props.editable}
glosses={sense.glosses}
idPrefix={`row-${props.rowData.id}-gloss`}
key={`row-${props.rowData.id}-gloss`}
onChange={(glosses) =>
props.onRowDataChange &&
props.onRowDataChange({
...props.rowData,
senses: [
...props.rowData.senses.slice(0, index),
{ ...sense, glosses },
...props.rowData.senses.slice(index + 1),
],
})
}
/>
<Overlay key={index} on={sense.deleted}>
<GlossList
defaultLang={analysisLang}
editable={props.editable && !sense.deleted}
glosses={sense.glosses}
idPrefix={`row-${props.rowData.id}-gloss`}
onChange={(glosses) =>
props.onRowDataChange &&
props.onRowDataChange({
...props.rowData,
senses: [
...props.rowData.senses.slice(0, index),
{ ...sense, glosses },
...props.rowData.senses.slice(index + 1),
],
})
}
/>
</Overlay>
))}
bottomCell={props.editable ? SPACER : undefined}
/>
Expand Down Expand Up @@ -94,12 +96,12 @@ function GlossList(props: GlossListProps): ReactElement {
<GlossField
gloss={g}
key={i}
textFieldId={`${props.idPrefix}-${i}-text`}
onChange={(gloss: Gloss) => {
const updatedGlosses = [...glosses];
updatedGlosses.splice(i, 1, gloss);
props.onChange(updatedGlosses);
}}
textFieldId={`${props.idPrefix}-${i}-text`}
/>
))}
</>
Expand Down

0 comments on commit 7947492

Please sign in to comment.