Skip to content

Commit

Permalink
Add project setting for overriding protected words/senses
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec committed Nov 13, 2024
1 parent e21032c commit 04400e2
Show file tree
Hide file tree
Showing 20 changed files with 133 additions and 41 deletions.
3 changes: 2 additions & 1 deletion Backend.Tests/Models/ProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public void TestClone()
LiftImported = true,
DefinitionsEnabled = true,
GrammaticalInfoEnabled = true,
AutocompleteSetting = AutocompleteSetting.On,
AutocompleteSetting = OffOnSetting.On,
ProtectedDataOverrideEnabled = OffOnSetting.Off,
SemDomWritingSystem = new("fr", "Français"),
VernacularWritingSystem = new("en", "English", "Calibri"),
AnalysisWritingSystems = new() { new("es", "Español") },
Expand Down
17 changes: 13 additions & 4 deletions Backend/Models/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ public class Project
[Required]
[BsonElement("autocompleteSetting")]
[BsonRepresentation(BsonType.String)]
public AutocompleteSetting AutocompleteSetting { get; set; }
public OffOnSetting AutocompleteSetting { get; set; }

[Required]
[BsonElement("protectedDataOverrideEnabled")]
[BsonRepresentation(BsonType.String)]
public OffOnSetting ProtectedDataOverrideEnabled { get; set; }

[Required]
[BsonElement("semDomWritingSystem")]
Expand Down Expand Up @@ -92,7 +97,8 @@ public Project()
LiftImported = false;
DefinitionsEnabled = false;
GrammaticalInfoEnabled = false;
AutocompleteSetting = AutocompleteSetting.On;
AutocompleteSetting = OffOnSetting.On;
ProtectedDataOverrideEnabled = OffOnSetting.Off;
SemDomWritingSystem = new();
VernacularWritingSystem = new();
AnalysisWritingSystems = new();
Expand All @@ -117,6 +123,7 @@ public Project Clone()
DefinitionsEnabled = DefinitionsEnabled,
GrammaticalInfoEnabled = GrammaticalInfoEnabled,
AutocompleteSetting = AutocompleteSetting,
ProtectedDataOverrideEnabled = ProtectedDataOverrideEnabled,
SemDomWritingSystem = SemDomWritingSystem.Clone(),
VernacularWritingSystem = VernacularWritingSystem.Clone(),
AnalysisWritingSystems = AnalysisWritingSystems.Select(ws => ws.Clone()).ToList(),
Expand All @@ -140,6 +147,7 @@ public bool ContentEquals(Project other)
other.DefinitionsEnabled == DefinitionsEnabled &&
other.GrammaticalInfoEnabled == GrammaticalInfoEnabled &&
other.AutocompleteSetting.Equals(AutocompleteSetting) &&
other.ProtectedDataOverrideEnabled.Equals(ProtectedDataOverrideEnabled) &&
other.SemDomWritingSystem.Equals(SemDomWritingSystem) &&
other.VernacularWritingSystem.Equals(VernacularWritingSystem) &&

Expand Down Expand Up @@ -186,11 +194,12 @@ public override int GetHashCode()
var hash = new HashCode();
hash.Add(Id);
hash.Add(Name);
hash.Add(IsActive);
hash.Add(LiftImported);
hash.Add(DefinitionsEnabled);
hash.Add(GrammaticalInfoEnabled);
hash.Add(IsActive);
hash.Add(AutocompleteSetting);
hash.Add(ProtectedDataOverrideEnabled);
hash.Add(SemDomWritingSystem);
hash.Add(VernacularWritingSystem);
hash.Add(AnalysisWritingSystems);
Expand Down Expand Up @@ -329,7 +338,7 @@ public UserCreatedProject()
}
}

public enum AutocompleteSetting
public enum OffOnSetting
{
Off,
On
Expand Down
4 changes: 2 additions & 2 deletions Backend/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public class User
[Required]
[BsonElement("glossSuggestion")]
[BsonRepresentation(BsonType.String)]
public AutocompleteSetting GlossSuggestion { get; set; }
public OffOnSetting GlossSuggestion { get; set; }

[Required]
[BsonElement("token")]
Expand All @@ -98,7 +98,7 @@ public User()
Password = "";
Username = "";
UILang = "";
GlossSuggestion = AutocompleteSetting.On;
GlossSuggestion = OffOnSetting.On;
Token = "";
IsAdmin = false;
WorkedProjects = new();
Expand Down
1 change: 1 addition & 0 deletions Backend/Repositories/ProjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public async Task<ResultOfUpdate> Update(string projectId, Project project)
.Set(x => x.DefinitionsEnabled, project.DefinitionsEnabled)
.Set(x => x.GrammaticalInfoEnabled, project.GrammaticalInfoEnabled)
.Set(x => x.AutocompleteSetting, project.AutocompleteSetting)
.Set(x => x.ProtectedDataOverrideEnabled, project.ProtectedDataOverrideEnabled)
.Set(x => x.SemDomWritingSystem, project.SemDomWritingSystem)
.Set(x => x.VernacularWritingSystem, project.VernacularWritingSystem)
.Set(x => x.AnalysisWritingSystems, project.AnalysisWritingSystems)
Expand Down
4 changes: 4 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@
"on": "On",
"hint": "In Data Entry, suggest existing Vernaculars similar to the Vernacular being typed."
},
"protectedDataOverride": {
"hint": "In Merge Duplicates, allow overriding protection of protected words and senses.",
"label": "Protected Data Override"
},
"invite": {
"inviteByEmailLabel": "Invite by Email",
"userExists": "This user is already registered.",
Expand Down
2 changes: 1 addition & 1 deletion src/api/.openapi-generator/FILES
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ common.ts
configuration.ts
git_push.sh
index.ts
models/autocomplete-setting.ts
models/banner-type.ts
models/chart-root-data.ts
models/consent-type.ts
Expand All @@ -42,6 +41,7 @@ models/merge-source-word.ts
models/merge-undo-ids.ts
models/merge-words.ts
models/note.ts
models/off-on-setting.ts
models/password-reset-data.ts
models/password-reset-request-data.ts
models/permission.ts
Expand Down
2 changes: 1 addition & 1 deletion src/api/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from "./autocomplete-setting";
export * from "./banner-type";
export * from "./chart-root-data";
export * from "./consent-type";
Expand All @@ -18,6 +17,7 @@ export * from "./merge-source-word";
export * from "./merge-undo-ids";
export * from "./merge-words";
export * from "./note";
export * from "./off-on-setting";
export * from "./password-reset-data";
export * from "./password-reset-request-data";
export * from "./permission";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @export
* @enum {string}
*/
export enum AutocompleteSetting {
export enum OffOnSetting {
Off = "Off",
On = "On",
}
12 changes: 9 additions & 3 deletions src/api/models/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
* Do not edit the class manually.
*/

import { AutocompleteSetting } from "./autocomplete-setting";
import { CustomField } from "./custom-field";
import { EmailInvite } from "./email-invite";
import { OffOnSetting } from "./off-on-setting";
import { SemanticDomainFull } from "./semantic-domain-full";
import { WritingSystem } from "./writing-system";

Expand Down Expand Up @@ -62,10 +62,16 @@ export interface Project {
grammaticalInfoEnabled: boolean;
/**
*
* @type {AutocompleteSetting}
* @type {OffOnSetting}
* @memberof Project
*/
autocompleteSetting: AutocompleteSetting;
autocompleteSetting: OffOnSetting;
/**
*
* @type {OffOnSetting}
* @memberof Project
*/
protectedDataOverrideEnabled: OffOnSetting;
/**
*
* @type {WritingSystem}
Expand Down
14 changes: 7 additions & 7 deletions src/api/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* Do not edit the class manually.
*/

import { AutocompleteSetting } from "./autocomplete-setting";
import { OffOnSetting } from "./off-on-setting";

/**
*
Expand Down Expand Up @@ -100,20 +100,20 @@ export interface User {
uiLang?: string | null;
/**
*
* @type {string}
* @type {OffOnSetting}
* @memberof User
*/
token: string;
glossSuggestion: OffOnSetting;
/**
*
* @type {boolean}
* @type {string}
* @memberof User
*/
isAdmin: boolean;
token: string;
/**
*
* @type {AutocompleteSetting}
* @type {boolean}
* @memberof User
*/
glossSuggestion: AutocompleteSetting;
isAdmin: boolean;
}
7 changes: 3 additions & 4 deletions src/components/DataEntry/DataEntryTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { useTranslation } from "react-i18next";
import { v4 } from "uuid";

import {
AutocompleteSetting,
Note,
OffOnSetting,
Pronunciation,
SemanticDomain,
SemanticDomainTreeNode,
Expand Down Expand Up @@ -250,8 +250,7 @@ export default function DataEntryTable(
);
const suggestVerns = useAppSelector(
(state: StoreState) =>
state.currentProjectState.project.autocompleteSetting ===
AutocompleteSetting.On
state.currentProjectState.project.autocompleteSetting === OffOnSetting.On
);
const vernacularLang = useAppSelector(
(state: StoreState) =>
Expand All @@ -272,7 +271,7 @@ export default function DataEntryTable(
const spellChecker = useContext(SpellCheckerContext);
useEffect(() => {
spellChecker.updateLang(
getCurrentUser()?.glossSuggestion === AutocompleteSetting.Off
getCurrentUser()?.glossSuggestion === OffOnSetting.Off
? undefined
: analysisLang.bcp47
);
Expand Down
10 changes: 5 additions & 5 deletions src/components/ProjectSettings/ProjectAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Grid, MenuItem, Select, Tooltip } from "@mui/material";
import { type ReactElement } from "react";
import { useTranslation } from "react-i18next";

import { AutocompleteSetting } from "api/models";
import { OffOnSetting } from "api/models";
import { type ProjectSettingProps } from "components/ProjectSettings/ProjectSettingsTypes";

export default function ProjectAutocomplete(
Expand All @@ -12,7 +12,7 @@ export default function ProjectAutocomplete(
const { t } = useTranslation();

const updateAutocompleteSetting = async (
autocompleteSetting: AutocompleteSetting
autocompleteSetting: OffOnSetting
): Promise<void> => {
await props.setProject({ ...props.project, autocompleteSetting });
};
Expand All @@ -24,13 +24,13 @@ export default function ProjectAutocomplete(
variant="standard"
value={props.project.autocompleteSetting}
onChange={(e) =>
updateAutocompleteSetting(e.target.value as AutocompleteSetting)
updateAutocompleteSetting(e.target.value as OffOnSetting)
}
>
<MenuItem value={AutocompleteSetting.Off}>
<MenuItem value={OffOnSetting.Off}>
{t("projectSettings.autocomplete.off")}
</MenuItem>
<MenuItem value={AutocompleteSetting.On}>
<MenuItem value={OffOnSetting.On}>
{t("projectSettings.autocomplete.on")}
</MenuItem>
</Select>
Expand Down
48 changes: 48 additions & 0 deletions src/components/ProjectSettings/ProjectProtectedOverride.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { HelpOutline } from "@mui/icons-material";
import { Grid, MenuItem, Select, Tooltip } from "@mui/material";
import { type ReactElement } from "react";
import { useTranslation } from "react-i18next";

import { OffOnSetting } from "api/models";
import { type ProjectSettingProps } from "components/ProjectSettings/ProjectSettingsTypes";

export default function ProjectProtectedOverride(
props: ProjectSettingProps
): ReactElement {
const { t } = useTranslation();

const updateProtectOverrideSetting = async (
protectedDataOverrideEnabled: OffOnSetting
): Promise<void> => {
await props.setProject({ ...props.project, protectedDataOverrideEnabled });
};

return (
<Grid container>
<Grid>
<Select
variant="standard"
value={props.project.protectedDataOverrideEnabled}
onChange={(e) =>
updateProtectOverrideSetting(e.target.value as OffOnSetting)
}
>
<MenuItem value={OffOnSetting.Off}>
{t("projectSettings.autocomplete.off")}
</MenuItem>
<MenuItem value={OffOnSetting.On}>
{t("projectSettings.autocomplete.on")}
</MenuItem>
</Select>
</Grid>
<Grid>
<Tooltip
title={t("projectSettings.protectedDataOverride.hint")}
placement={document.body.dir === "rtl" ? "left" : "right"}
>
<HelpOutline fontSize="small" />
</Tooltip>
</Grid>
</Grid>
);
}
17 changes: 17 additions & 0 deletions src/components/ProjectSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
People,
PersonAdd,
RecordVoiceOver,
RemoveModerator,
Settings,
Sms,
} from "@mui/icons-material";
Expand Down Expand Up @@ -53,6 +54,7 @@ import ProjectLanguages, {
SemanticDomainLanguage,
} from "components/ProjectSettings/ProjectLanguages";
import ProjectName from "components/ProjectSettings/ProjectName";
import ProjectProtectedOverride from "components/ProjectSettings/ProjectProtectedOverride";
import ProjectSchedule from "components/ProjectSettings/ProjectSchedule";
import ProjectSelect from "components/ProjectSettings/ProjectSelect";
import ActiveProjectUsers from "components/ProjectUsers/ActiveProjectUsers";
Expand Down Expand Up @@ -80,6 +82,7 @@ export enum Setting {
Import = "SettingImport",
Languages = "SettingLanguages",
Name = "SettingName",
ProtectOverride = "SettingProtectOverride",
Schedule = "SettingSchedule",
Speakers = "SettingSpeakers",
UserAdd = "SettingUserAdd",
Expand Down Expand Up @@ -176,6 +179,20 @@ export default function ProjectSettingsComponent(): ReactElement {
/>
)}

{/* Protected data override toggle */}
{permissions.includes(Permission.DeleteEditSettingsAndUsers) && (
<BaseSettings
icon={<RemoveModerator data-testid={Setting.ProtectOverride} />}
title={t("projectSettings.protectedDataOverride.label")}
body={
<ProjectProtectedOverride
project={project}
setProject={updateProject}
/>
}
/>
)}

{/* Archive project */}
{permissions.includes(Permission.Archive) && (
<BaseSettings
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Select } from "@mui/material";
import renderer from "react-test-renderer";

import { AutocompleteSetting } from "api/models";
import { OffOnSetting } from "api/models";
import ProjectAutocomplete from "components/ProjectSettings/ProjectAutocomplete";
import { randomProject } from "types/project";

Expand All @@ -26,12 +26,12 @@ describe("ProjectAutocomplete", () => {
await renderer.act(async () => selectChange({ target: { value: "Off" } }));
expect(mockSetProject).toHaveBeenCalledWith({
...mockProject,
autocompleteSetting: AutocompleteSetting.Off,
autocompleteSetting: OffOnSetting.Off,
});
await renderer.act(async () => selectChange({ target: { value: "On" } }));
expect(mockSetProject).toHaveBeenCalledWith({
...mockProject,
autocompleteSetting: AutocompleteSetting.On,
autocompleteSetting: OffOnSetting.On,
});
});
});
Loading

0 comments on commit 04400e2

Please sign in to comment.