Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MergeDups] Enable bypassing protection of protected words and senses #3445

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
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
11 changes: 8 additions & 3 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 Expand Up @@ -410,10 +414,11 @@
"delete": "Delete sense",
"deleteDialog": "Delete this sense?",
"protectedSense": "This sense was imported with data that The Combine doesn't handle.",
"protectedSenseInfo": "This sense cannot be deleted or dropped into another sense. You may still move it to another word or drop other senses into this one to merge them.",
"protectedSenseInfo": "This sense cannot be safely deleted or dropped into another sense. You may still move it to another word or drop other senses into this one to merge them.",
"protectedWord": "This word was imported with data that The Combine doesn't handle.",
"protectedWordInfo": "To prevent deletion, the final sense of this word cannot be removed.",
"protectedData": "Protected data: {{ val }}"
"protectedWordInfo": "To prevent deletion, the final sense of this word cannot be safely removed.",
"protectedData": "Protected data: {{ val }}",
"protectedOverrideWarning": "The following data will be lost: {{ val }}"
},
"protectReason": {
"annotations": "annotations",
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
Loading
Loading