diff --git a/packages/client/public/locales/en/translation.json b/packages/client/public/locales/en/translation.json
index ccc51111..1a4631d1 100644
--- a/packages/client/public/locales/en/translation.json
+++ b/packages/client/public/locales/en/translation.json
@@ -5,7 +5,22 @@
"instruction": "Instruction",
"project": "Project",
"study": "Study",
- "submit": "Submit"
+ "submit": "Submit",
+ "delete": "Delete",
+ "cancel": "Cancel",
+ "ok": "OK",
+ "email": "Email",
+ "back": "Back",
+ "finish": "Finish",
+ "next": "Next",
+ "continue": "Continue",
+ "required": "Required",
+ "preview": "Preview",
+ "enable": "Enable",
+ "view": "View",
+ "entryId": "Entry ID",
+ "login": "Login",
+ "clear": "clear"
},
"languages": {
"en": "English",
@@ -24,7 +39,7 @@
"studies": "Studies",
"newStudy": "New Study",
"studyControl": "Study Control",
- "entryControls": "Entry Controls",
+ "entryControl": "Entry Control",
"downloadTags": "Download Tags",
"datasets": "Datasets",
"datasetControl": "Dataset Control",
@@ -44,7 +59,64 @@
"formLabel": "Create New Project",
"nameDescription": "Please enter project name",
"descriptionDescription": "Please enter project description",
+ "failMessage": " Failed to create project! Try again.",
+ "projectExists": "A project with this name already exists"
+ },
+ "projectControl": {
+ "deleteStudy": "Delete Study",
+ "deleteDescription": "Are you sure you want to delete this project? Doing so will delete all contained studies and tags"
+ },
+ "datasetControl": {
+ "deleteEntry": "Delete Entry",
+ "deleteDescription": "Are you sure you want to delete this project? Doing so will delete all associated tags",
+ "addDataset": " Add New Dataset",
+ "uploadEntries": " Upload Entries"
+ },
+ "projectAccess": {
+ "datasetName": "Dataset Name",
+ "projectHasAccess": "Project Has Access",
+ "accessFor": "Dataset Access for ",
+ "selectProject": "Select a Project to Continue"
+ },
+ "userPermissions": {
+ "studyAdmin": "Study Admin",
+ "contributor": "Contributor",
+ "trained": "Trained"
+ },
+ "projectUserPermissions": {
+ "projectAdmin": "Project Admin",
+ "contributor": "Contributor",
+ "trained": "Trained"
+ },
+ "newStudy": {
+ "createStudy": "Create New Study",
+ "steps": {
+ "Study Identification": "Study Identification",
+ "Construct Tagging Interface": "Construct Tagging Interface",
+ "Select Tag Training Items": "Select Tag Training Items"
+ },
+ "completed": "All steps completed - your new study is created",
+ "startOver": "Start Over",
+ "formTitle": "Study Information",
+ "tagsDescription": "Number of times each entry needs to be tagged (default 1)"
+ },
+ "studyControl": {
+ "deleteStudy": "Delete Study",
+ "deleteDescription": "Are you sure you want to delete this study? Doing so will delete all contained tags"
+ },
+ "contribute": {
+ "enterTagging": "Enter tagging",
+ "noTaggingLeft": "No tagging left",
+ "studyTraining": "Study Training",
+ "studyTagging": "Study Tagging",
"failMessage": " Failed to create project! Try again."
+ },
+ "successPage": {
+ "succefullyCreated": "Successfully created!"
+ },
+ "login": {
+ "selectOrg": "Select an Organization to Login",
+ "redirectToOrg": "Redirect to Organization Login"
}
}
}
diff --git a/packages/client/src/components/DatasetAccess.component.tsx b/packages/client/src/components/DatasetAccess.component.tsx
index b1f0ea36..cf6d5c00 100644
--- a/packages/client/src/components/DatasetAccess.component.tsx
+++ b/packages/client/src/components/DatasetAccess.component.tsx
@@ -3,6 +3,7 @@ import useEnhancedEffect from '@mui/material/utils/useEnhancedEffect';
import { DataGrid, GridColDef, GridRenderCellParams, useGridApiContext } from '@mui/x-data-grid';
import { GridRowModesModel } from '@mui/x-data-grid-pro';
import { useRef, useState } from 'react';
+import { useTranslation } from 'react-i18next';
interface Row {
id: number;
@@ -41,6 +42,7 @@ const renderSwitchEditInputCell: GridColDef['renderCell'] = (params) => {
export const DatasetAccess: React.FC
= ({ tableRows }: Table) => {
const [rows] = useState(tableRows);
const [rowModesModel, setRowModesModel] = useState({});
+ const { t } = useTranslation();
const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => {
setRowModesModel(newRowModesModel);
@@ -50,20 +52,20 @@ export const DatasetAccess: React.FC = ({ tableRows }: Table) => {
{ field: 'id', headerName: 'ID', width: 55 },
{
field: 'name',
- headerName: 'Name',
+ headerName: t('common.name'),
width: 200,
editable: true
},
{
field: 'description',
- headerName: 'Description',
+ headerName: t('common.description'),
width: 450,
editable: true
},
{
field: 'switch',
type: 'boolean',
- headerName: 'Project Access',
+ headerName: t('menu.projectAccess'),
renderCell: (params) => ,
renderEditCell: renderSwitchEditInputCell,
editable: true,
diff --git a/packages/client/src/components/DatasetTable.component.tsx b/packages/client/src/components/DatasetTable.component.tsx
index f2ef5c46..4fc93808 100644
--- a/packages/client/src/components/DatasetTable.component.tsx
+++ b/packages/client/src/components/DatasetTable.component.tsx
@@ -3,6 +3,7 @@ import { useState, useEffect } from 'react';
import { Dataset, Entry } from '../graphql/graphql';
import { useEntryForDatasetLazyQuery } from '../graphql/entry/entry';
import { EntryView } from './EntryView.component';
+import { useTranslation } from 'react-i18next';
export interface DatasetTableProps {
dataset: Dataset;
@@ -10,16 +11,18 @@ export interface DatasetTableProps {
}
export const DatasetTable: React.FC = (props) => {
+ const { t } = useTranslation();
+
const defaultColumns: GridColDef[] = [
{
field: 'view',
- headerName: 'View',
+ headerName: t('common.view'),
width: 300,
renderCell: (params) =>
},
{
field: 'entryID',
- headerName: 'Entry ID',
+ headerName: t('common.entryId'),
width: 150,
editable: false
}
diff --git a/packages/client/src/components/NewStudyJsonForm.component.tsx b/packages/client/src/components/NewStudyJsonForm.component.tsx
index c40460b5..c4895a89 100644
--- a/packages/client/src/components/NewStudyJsonForm.component.tsx
+++ b/packages/client/src/components/NewStudyJsonForm.component.tsx
@@ -5,6 +5,7 @@ import { PartialStudyCreate } from '../types/study';
import { ErrorObject } from 'ajv';
import { useStudyExistsLazyQuery } from '../graphql/study/study';
import { useProject } from '../context/Project.context';
+import { useTranslation } from 'react-i18next';
export interface NewStudyFormProps {
newStudy: PartialStudyCreate | null;
@@ -12,11 +13,6 @@ export interface NewStudyFormProps {
}
export const NewStudyJsonForm: React.FC = (props) => {
- const initialData = {
- tagsPerEntry: schema.properties.tagsPerEntry.default
- };
-
- const [data, setData] = useState(initialData);
const [studyExistsQuery, studyExistsResults] = useStudyExistsLazyQuery();
const { project } = useProject();
const [additionalErrors, setAdditionalErrors] = useState([]);
@@ -24,6 +20,60 @@ export const NewStudyJsonForm: React.FC = (props) => {
// Keep track of the new study internally to check to make sure the name is
// unique before submitting
const [potentialNewStudy, setPotentialNewStudy] = useState(null);
+ const { t } = useTranslation();
+
+ const schema = {
+ type: 'object',
+ properties: {
+ name: {
+ type: 'string',
+ pattern: '^[a-zA-Z 0-9]*$'
+ },
+ description: {
+ type: 'string'
+ },
+ instructions: {
+ type: 'string'
+ },
+ tagsPerEntry: {
+ type: 'number',
+ default: 1
+ }
+ },
+ required: ['name', 'description', 'instructions', 'tagsPerEntry']
+ };
+
+ const uischema = {
+ type: 'Group',
+ label: t('components.newStudy.formTitle'),
+ elements: [
+ {
+ type: 'Control',
+ label: t('common.name'),
+ scope: '#/properties/name'
+ },
+ {
+ type: 'Control',
+ label: t('common.description'),
+ scope: '#/properties/description'
+ },
+ {
+ type: 'Control',
+ label: t('common.instruction'),
+ scope: '#/properties/instructions'
+ },
+ {
+ type: 'Control',
+ label: t('components.newStudy.tagsDescription'),
+ scope: '#/properties/tagsPerEntry'
+ }
+ ]
+ };
+
+ const initialData = {
+ tagsPerEntry: schema.properties.tagsPerEntry.default
+ };
+ const [data, setData] = useState(initialData);
const handleChange = (data: any, errors: ErrorObject[] | undefined) => {
setData(data);
@@ -68,51 +118,3 @@ export const NewStudyJsonForm: React.FC = (props) => {
/>
);
};
-
-const schema = {
- type: 'object',
- properties: {
- name: {
- type: 'string',
- pattern: '^[a-zA-Z 0-9]*$'
- },
- description: {
- type: 'string'
- },
- instructions: {
- type: 'string'
- },
- tagsPerEntry: {
- type: 'number',
- default: 1
- }
- },
- required: ['name', 'description', 'instructions', 'tagsPerEntry']
-};
-
-const uischema = {
- type: 'Group',
- label: 'Study Information',
- elements: [
- {
- type: 'Control',
- label: 'Name',
- scope: '#/properties/name'
- },
- {
- type: 'Control',
- label: 'Description',
- scope: '#/properties/description'
- },
- {
- type: 'Control',
- label: 'Instructions',
- scope: '#/properties/instructions'
- },
- {
- type: 'Control',
- label: 'Number of times each entry needs to be tagged (default 1)',
- scope: '#/properties/tagsPerEntry'
- }
- ]
-};
diff --git a/packages/client/src/components/SideBar.component.tsx b/packages/client/src/components/SideBar.component.tsx
index 98dde7ca..5144739d 100644
--- a/packages/client/src/components/SideBar.component.tsx
+++ b/packages/client/src/components/SideBar.component.tsx
@@ -62,7 +62,7 @@ export const SideBar: FC = ({ open, drawerWidth }) => {
action: () => navigate('/study/permissions'),
visible: (p) => p!.studyAdmin
},
- { name: t('menu.entryControls'), action: () => navigate('/study/entries'), visible: (p) => p!.studyAdmin },
+ { name: t('menu.entryControl'), action: () => navigate('/study/entries'), visible: (p) => p!.studyAdmin },
{ name: t('menu.downloadTags'), action: () => navigate('/study/tags'), visible: (p) => p!.studyAdmin }
]
},
diff --git a/packages/client/src/components/contribute/TagForm.component.tsx b/packages/client/src/components/contribute/TagForm.component.tsx
index f4c62151..98da1e16 100644
--- a/packages/client/src/components/contribute/TagForm.component.tsx
+++ b/packages/client/src/components/contribute/TagForm.component.tsx
@@ -8,6 +8,7 @@ import AslLexSearchControl from '../tag/asllex/AslLexSearchControl';
import AslLexSearchControlTester from '../tag/asllex/aslLexSearchControlTester';
import VideoRecordField, { videoFieldTester } from '../tag/videorecord/VideoRecordField.component';
import { JsonFormsRendererRegistryEntry } from '@jsonforms/core';
+import { useTranslation } from 'react-i18next';
export interface TagFormProps {
study: Study;
@@ -17,6 +18,7 @@ export interface TagFormProps {
export const TagForm: React.FC = (props) => {
const [data, setData] = useState();
const [dataValid, setDataValid] = useState(false);
+ const { t } = useTranslation();
const handleFormChange = (data: any, errors: ErrorObject[] | undefined) => {
setData(data);
@@ -62,10 +64,10 @@ export const TagForm: React.FC = (props) => {
/>
diff --git a/packages/client/src/context/Confirmation.context.tsx b/packages/client/src/context/Confirmation.context.tsx
index 057099e1..8854ca22 100644
--- a/packages/client/src/context/Confirmation.context.tsx
+++ b/packages/client/src/context/Confirmation.context.tsx
@@ -1,5 +1,6 @@
import { createContext, useContext, useState } from 'react';
import { Dialog, DialogContent, DialogTitle, DialogActions, Button, Typography } from '@mui/material';
+import { useTranslation } from 'react-i18next';
export interface ConfirmationRequest {
message: string;
@@ -21,6 +22,7 @@ export interface ConfirmationProviderProps {
export const ConfirmationProvider: React.FC = ({ children }) => {
const [open, setOpen] = useState(false);
const [confirmationRequest, setConfirmationRequest] = useState(null);
+ const { t } = useTranslation();
const pushConfirmationRequest = (confirmationRequest: ConfirmationRequest) => {
setConfirmationRequest(confirmationRequest);
@@ -50,9 +52,9 @@ export const ConfirmationProvider: React.FC = ({ chil
-
+
{children}
diff --git a/packages/client/src/pages/LoginPage.tsx b/packages/client/src/pages/LoginPage.tsx
index 6abdbce3..79ebf88d 100644
--- a/packages/client/src/pages/LoginPage.tsx
+++ b/packages/client/src/pages/LoginPage.tsx
@@ -4,11 +4,13 @@ import { useAuth } from '../context/Auth.context';
import { useNavigate } from 'react-router-dom';
import { Organization } from '../graphql/graphql';
import { useGetOrganizationsQuery } from '../graphql/organization/organization';
+import { useTranslation } from 'react-i18next';
export const LoginPage: FC = () => {
// Construct the Auth URL
const { authenticated } = useAuth();
const navigate = useNavigate();
+ const { t } = useTranslation();
const [organization, setOrganization] = useState(null);
const [authURL, setAuthURL] = useState(null);
@@ -62,7 +64,7 @@ export const LoginPage: FC = () => {
alignItems: 'center'
}}
>
- Login
+ {t('common.login')}
diff --git a/packages/client/src/pages/SuccessPage.tsx b/packages/client/src/pages/SuccessPage.tsx
index 3ac27e80..82076a3c 100644
--- a/packages/client/src/pages/SuccessPage.tsx
+++ b/packages/client/src/pages/SuccessPage.tsx
@@ -1,11 +1,14 @@
import { Typography, Button } from '@mui/material';
+import { useTranslation } from 'react-i18next';
export const SuccessPage = () => {
+ const { t } = useTranslation();
+
return (
- Successfully created!
+ {t('components.successPage.succefullyCreated')}
);
diff --git a/packages/client/src/pages/contribute/ContributeLanding.tsx b/packages/client/src/pages/contribute/ContributeLanding.tsx
index 5272fd17..d57b7241 100644
--- a/packages/client/src/pages/contribute/ContributeLanding.tsx
+++ b/packages/client/src/pages/contribute/ContributeLanding.tsx
@@ -2,11 +2,13 @@ import { Typography, Box, Stack, Button } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { useStudy } from '../../context/Study.context';
import { TagProvider, useTag } from '../../context/Tag.context';
+import { useTranslation } from 'react-i18next';
const ContributeLandingInternal: React.FC = () => {
const navigate = useNavigate();
const { study } = useStudy();
const { tag } = useTag();
+ const { t } = useTranslation();
const enterTagging = () => {
navigate('/contribute/tagging');
@@ -18,17 +20,27 @@ const ContributeLandingInternal: React.FC = () => {
<>
{study && (
- Study: {study.name}
+
+ {t('common.study')}: {study.name}
+
- {false ? 'Study Training' : 'Study Tagging'}
- Study: {study.name}
- Description: {study.description}
- Instructions: {study.instructions}
+
+ {false ? t('components.contribute.studyTraining') : t('components.contribute.studyTagging')}
+
+
+ {t('common.study')}: {study.name}
+
+
+ {t('common.description')}: {study.description}
+
+
+ {t('common.instruction')}: {study.instructions}
+
)}
diff --git a/packages/client/src/pages/datasets/DatasetControls.tsx b/packages/client/src/pages/datasets/DatasetControls.tsx
index 44164ab5..a66f93c5 100644
--- a/packages/client/src/pages/datasets/DatasetControls.tsx
+++ b/packages/client/src/pages/datasets/DatasetControls.tsx
@@ -10,6 +10,7 @@ import { GridColDef, GridActionsCellItem, GridRowId } from '@mui/x-data-grid';
import DeleteIcon from '@mui/icons-material/DeleteOutlined';
import { useConfirmation } from '../../context/Confirmation.context';
import { useDeleteEntryMutation } from '../../graphql/entry/entry';
+import { useTranslation } from 'react-i18next';
export const DatasetControls: React.FC = () => {
const [add, setAdd] = useState(false);
@@ -17,6 +18,7 @@ export const DatasetControls: React.FC = () => {
const [datasets, setDatasets] = useState([]);
const [getDatasets, getDatasetsResults] = useGetDatasetsLazyQuery();
const [deleteEntryMutation] = useDeleteEntryMutation();
+ const { t } = useTranslation();
const confirmation = useConfirmation();
@@ -52,8 +54,8 @@ export const DatasetControls: React.FC = () => {
const handleDelete = async (id: GridRowId) => {
// Execute delete mutation
confirmation.pushConfirmationRequest({
- title: 'Delete Entry',
- message: 'Are you sure you want to delete this project? Doing so will delete all associated tags',
+ title: t('components.datasetControl.deleteEntry'),
+ message: t('components.datasetControl.deleteDescription'),
onConfirm: async () => {
const res = await deleteEntryMutation({ variables: { entry: id.toString() } });
if (res.errors) {
@@ -71,7 +73,7 @@ export const DatasetControls: React.FC = () => {
{
field: 'delete',
type: 'actions',
- headerName: 'Delete',
+ headerName: t('common.delete'),
width: 120,
maxWidth: 120,
cellClassName: 'delete',
@@ -79,7 +81,7 @@ export const DatasetControls: React.FC = () => {
return [
}
- label="Delete"
+ label={t('common.delete')}
onClick={() => handleDelete(params.id)}
/>
];
@@ -89,7 +91,7 @@ export const DatasetControls: React.FC = () => {
return (
<>
- Dataset Controls
+ {t('menu.datasetControl')}
{
- Add New Dataset
+ {t('components.datasetControl.addDataset')}
{
- Upload Entries
+ {t('components.datasetControl.uploadEntries')}
diff --git a/packages/client/src/pages/datasets/ProjectAccess.tsx b/packages/client/src/pages/datasets/ProjectAccess.tsx
index 9fb082c8..c0fc8a48 100644
--- a/packages/client/src/pages/datasets/ProjectAccess.tsx
+++ b/packages/client/src/pages/datasets/ProjectAccess.tsx
@@ -5,12 +5,14 @@ import { useGetDatasetProjectPermissionsLazyQuery } from '../../graphql/permissi
import { useEffect, useState } from 'react';
import { DatasetProjectPermission, Project } from '../../graphql/graphql';
import { useGrantProjectDatasetAccessMutation } from '../../graphql/permission/permission';
+import { useTranslation } from 'react-i18next';
export const ProjectAccess: React.FC = () => {
const { project } = useProject();
const [getDatasetProjectPermissions, datasetProjectPermissionResults] = useGetDatasetProjectPermissionsLazyQuery();
const [projectAccess, setProjectAccess] = useState([]);
const [grantProjectDatasetAccess, grantProjectDatasetAccessResults] = useGrantProjectDatasetAccessMutation();
+ const { t } = useTranslation();
// For querying for the permissions
useEffect(() => {
@@ -38,16 +40,21 @@ export const ProjectAccess: React.FC = () => {
};
const columns: GridColDef[] = [
- { field: 'name', headerName: 'Dataset Name', width: 200, valueGetter: (params) => params.row.dataset.name },
+ {
+ field: 'name',
+ headerName: t('components.projectAccess.datasetName'),
+ width: 200,
+ valueGetter: (params) => params.row.dataset.name
+ },
{
field: 'description',
- headerName: 'Description',
+ headerName: t('common.description'),
width: 200,
valueGetter: (params) => params.row.dataset.description
},
{
field: 'access',
- headerName: 'Project Has Access',
+ headerName: t('components.projectAccess.projectHasAccess'),
width: 200,
renderCell: (params) => (
@@ -59,11 +66,13 @@ export const ProjectAccess: React.FC = () => {
<>
{project ? (
<>
- Dataset Access for "{project.name}"
+
+ {t('components.projectAccess.accessFor')}"{project.name}"
+
row.dataset._id} />
>
) : (
- Select a Project to Continue
+ {t('components.projectAccess.selectProject')}
)}
>
);
diff --git a/packages/client/src/pages/projects/NewProject.tsx b/packages/client/src/pages/projects/NewProject.tsx
index 62d822ea..abe14f94 100644
--- a/packages/client/src/pages/projects/NewProject.tsx
+++ b/packages/client/src/pages/projects/NewProject.tsx
@@ -66,7 +66,7 @@ export const NewProject: React.FC = () => {
{
instancePath: '/name',
keyword: 'uniqueProjectName',
- message: 'A project with this name already exists',
+ message: t('components.newProject.projectExists'),
schemaPath: '#/properties/name/name',
params: { keyword: 'uniqueProjectName' }
}
@@ -116,7 +116,7 @@ export const NewProject: React.FC = () => {
additionalErrors={additionalErrors}
/>
>
);
diff --git a/packages/client/src/pages/projects/ProjectControl.tsx b/packages/client/src/pages/projects/ProjectControl.tsx
index 62471768..894a84b2 100644
--- a/packages/client/src/pages/projects/ProjectControl.tsx
+++ b/packages/client/src/pages/projects/ProjectControl.tsx
@@ -7,18 +7,20 @@ import { Project } from '../../graphql/graphql';
import { useDeleteProjectMutation } from '../../graphql/project/project';
import { useConfirmation } from '../../context/Confirmation.context';
import { useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
const ProjectControl: React.FC = () => {
const { projects, updateProjectList } = useProject();
const [deleteProjectMutation, deleteProjectResults] = useDeleteProjectMutation();
const confirmation = useConfirmation();
+ const { t } = useTranslation();
const handleDelete = async (id: GridRowId) => {
// Execute delete mutation
confirmation.pushConfirmationRequest({
- title: 'Delete Study',
- message: 'Are you sure you want to delete this project? Doing so will delete all contained studies and tags',
+ title: t('components.projectControl.deleteStudy'),
+ message: t('components.projectControl.deleteDescription'),
onConfirm: () => {
deleteProjectMutation({ variables: { project: id.toString() } });
},
@@ -36,32 +38,38 @@ const ProjectControl: React.FC = () => {
const columns: GridColDef[] = [
{
field: 'name',
- headerName: 'Name',
+ headerName: t('common.name'),
width: 200,
editable: false
},
{
field: 'description',
- headerName: 'Description',
+ headerName: t('common.description'),
width: 500,
editable: false
},
{
field: 'delete',
type: 'actions',
- headerName: 'Delete',
+ headerName: t('common.delete'),
width: 120,
maxWidth: 120,
cellClassName: 'delete',
getActions: (params) => {
- return [} label="Delete" onClick={() => handleDelete(params.id)} />];
+ return [
+ }
+ label={t('common.delete')}
+ onClick={() => handleDelete(params.id)}
+ />
+ ];
}
}
];
return (
<>
- Project Control
+ {t('menu.projectControl')}
row._id} />
diff --git a/packages/client/src/pages/projects/ProjectUserPermissions.tsx b/packages/client/src/pages/projects/ProjectUserPermissions.tsx
index 4d3a9674..7d649fd4 100644
--- a/packages/client/src/pages/projects/ProjectUserPermissions.tsx
+++ b/packages/client/src/pages/projects/ProjectUserPermissions.tsx
@@ -6,13 +6,15 @@ import { ProjectPermissionModel, Project } from '../../graphql/graphql';
import { useGetProjectPermissionsQuery } from '../../graphql/permission/permission';
import { DecodedToken, useAuth } from '../../context/Auth.context';
import { useGrantProjectPermissionsMutation } from '../../graphql/permission/permission';
+import { useTranslation } from 'react-i18next';
export const ProjectUserPermissions: React.FC = () => {
const { project } = useProject();
+ const { t } = useTranslation();
return (
<>
- User Permissions
+ {t('menu.userPermissions')}
{project && }
>
);
@@ -62,6 +64,7 @@ const UserPermissionTable: React.FC<{ project: Project }> = ({ project }) => {
const [rows, setRows] = useState([]);
const { decodedToken } = useAuth();
+ const { t } = useTranslation();
useEffect(() => {
if (data?.getProjectPermissions) {
@@ -88,7 +91,7 @@ const UserPermissionTable: React.FC<{ project: Project }> = ({ project }) => {
*/
{
field: 'email',
- headerName: 'Email',
+ headerName: t('common.email'),
valueGetter: (params) => params.row.user.email,
flex: 1.75,
editable: false
@@ -96,7 +99,7 @@ const UserPermissionTable: React.FC<{ project: Project }> = ({ project }) => {
{
field: 'projectAdmin',
type: 'boolean',
- headerName: 'Project Admin',
+ headerName: t('components.projectUserPermissions.projectAdmin'),
valueGetter: (params) => params.row.hasRole,
renderCell: (params: GridRenderCellParams) => {
return (
diff --git a/packages/client/src/pages/studies/DownloadTags.tsx b/packages/client/src/pages/studies/DownloadTags.tsx
index 6b32995d..c3ff29dd 100644
--- a/packages/client/src/pages/studies/DownloadTags.tsx
+++ b/packages/client/src/pages/studies/DownloadTags.tsx
@@ -1,11 +1,14 @@
import { Button, Container, Typography } from '@mui/material';
+import { useTranslation } from 'react-i18next';
export const DownloadTags: React.FC = () => {
+ const { t } = useTranslation();
+
return (
- Download Tags
+ {t('menu.downloadTags')}
);
diff --git a/packages/client/src/pages/studies/EntryControls.tsx b/packages/client/src/pages/studies/EntryControls.tsx
index f99688f4..428238c7 100644
--- a/packages/client/src/pages/studies/EntryControls.tsx
+++ b/packages/client/src/pages/studies/EntryControls.tsx
@@ -6,6 +6,7 @@ import { DatasetsView } from '../../components/DatasetsView.component';
import { useGetDatasetsByProjectQuery } from '../../graphql/dataset/dataset';
import { useProject } from '../../context/Project.context';
import ToggleEntryEnabled from '../../components/ToggleEntryEnabled.component';
+import { useTranslation } from 'react-i18next';
export const EntryControls: React.FC = () => {
const { project } = useProject();
@@ -15,6 +16,7 @@ export const EntryControls: React.FC = () => {
project: project ? project._id : ''
}
});
+ const { t } = useTranslation();
useEffect(() => {
if (getDatasetsByProjectResults.data) {
@@ -26,7 +28,7 @@ export const EntryControls: React.FC = () => {
{
field: 'enabled',
type: 'actions',
- headerName: 'Enable',
+ headerName: t('common.enable'),
width: 120,
maxWidth: 120,
cellClassName: 'enabled',
@@ -38,7 +40,7 @@ export const EntryControls: React.FC = () => {
return (
<>
- Entry Control
+ {t('menu.entryControl')}
>
);
diff --git a/packages/client/src/pages/studies/NewStudy.tsx b/packages/client/src/pages/studies/NewStudy.tsx
index 44bf3f77..8e269e54 100644
--- a/packages/client/src/pages/studies/NewStudy.tsx
+++ b/packages/client/src/pages/studies/NewStudy.tsx
@@ -10,6 +10,7 @@ import { useProject } from '../../context/Project.context';
import { useStudy } from '../../context/Study.context';
import { useApolloClient } from '@apollo/client';
import { CreateTagsDocument } from '../../graphql/tag/tag';
+import { useTranslation } from 'react-i18next';
export const NewStudy: React.FC = () => {
const [activeStep, setActiveStep] = useState(0);
@@ -21,6 +22,7 @@ export const NewStudy: React.FC = () => {
const [_trainingSet, setTrainingSet] = useState([]);
const [taggingSet, setTaggingSet] = useState([]);
const apolloClient = useApolloClient();
+ const { t } = useTranslation();
// Handles mantaining which step the user is on and the step limit
useEffect(() => {
@@ -109,22 +111,22 @@ export const NewStudy: React.FC = () => {
return (
<>
- Create New Study
+ {t('components.newStudy.createStudy')}
{steps.map((label) => {
return (
- {label}
+ {t('components.newStudy.steps.' + label)}
);
})}
{activeStep === steps.length ? (
<>
- All steps completed - your new study is created
+ {t('components.newStudy.completed')}
-
+
>
) : (
@@ -132,10 +134,10 @@ export const NewStudy: React.FC = () => {
{getSectionComponent()}
>
diff --git a/packages/client/src/pages/studies/StudyControl.tsx b/packages/client/src/pages/studies/StudyControl.tsx
index 96e6ab08..bda2db98 100644
--- a/packages/client/src/pages/studies/StudyControl.tsx
+++ b/packages/client/src/pages/studies/StudyControl.tsx
@@ -7,18 +7,20 @@ import { Study } from '../../graphql/graphql';
import { useDeleteStudyMutation } from '../../graphql/study/study';
import { useEffect } from 'react';
import { useConfirmation } from '../../context/Confirmation.context';
+import { useTranslation } from 'react-i18next';
export const StudyControl: React.FC = () => {
const { studies, updateStudies } = useStudy();
const [deleteStudyMutation, deleteStudyResults] = useDeleteStudyMutation();
const confirmation = useConfirmation();
+ const { t } = useTranslation();
const handleDelete = async (id: GridRowId) => {
// Execute delete mutation
confirmation.pushConfirmationRequest({
- title: 'Delete Study',
- message: 'Are you sure you want to delete this study? Doing so will delete all contained tags',
+ title: t('components.studyControl.deleteStudy'),
+ message: t('components.studyControl.deleteDescription'),
onConfirm: () => {
deleteStudyMutation({ variables: { study: id.toString() } });
},
@@ -36,32 +38,38 @@ export const StudyControl: React.FC = () => {
const columns: GridColDef[] = [
{
field: 'name',
- headerName: 'Name',
+ headerName: t('common.name'),
width: 200,
editable: false
},
{
field: 'description',
- headerName: 'Description',
+ headerName: t('common.description'),
width: 500,
editable: false
},
{
field: 'delete',
type: 'actions',
- headerName: 'Delete',
+ headerName: t('common.delete'),
width: 120,
maxWidth: 120,
cellClassName: 'delete',
getActions: (params) => {
- return [} label="Delete" onClick={() => handleDelete(params.id)} />];
+ return [
+ }
+ label={t('common.delete')}
+ onClick={() => handleDelete(params.id)}
+ />
+ ];
}
}
];
return (
<>
- Study Control
+ {t('menu.studyControl')}
row._id} />
diff --git a/packages/client/src/pages/studies/UserPermissions.tsx b/packages/client/src/pages/studies/UserPermissions.tsx
index f752d4cc..3bdc59cf 100644
--- a/packages/client/src/pages/studies/UserPermissions.tsx
+++ b/packages/client/src/pages/studies/UserPermissions.tsx
@@ -10,13 +10,15 @@ import {
useGrantTrainedContributorMutation
} from '../../graphql/permission/permission';
import { useEffect, useState } from 'react';
+import { useTranslation } from 'react-i18next';
export const StudyUserPermissions: React.FC = () => {
const { study } = useStudy();
+ const { t } = useTranslation();
return (
<>
- User Permissions
+ {t('menu.userPermissions')}
{study && }
>
);
@@ -122,6 +124,7 @@ const UserPermissionTable: React.FC<{ study: Study }> = ({ study }) => {
});
const [permissions, setPermissions] = useState([]);
+ const { t } = useTranslation();
useEffect(() => {
if (data) {
@@ -132,7 +135,7 @@ const UserPermissionTable: React.FC<{ study: Study }> = ({ study }) => {
const columns: GridColDef[] = [
{
field: 'email',
- headerName: 'Email',
+ headerName: t('common.email'),
valueGetter: (params) => params.row.user.email,
flex: 1.75,
editable: false
@@ -140,7 +143,7 @@ const UserPermissionTable: React.FC<{ study: Study }> = ({ study }) => {
{
field: 'studyAdmin',
type: 'boolean',
- headerName: 'Study Admin',
+ headerName: t('components.userPermissions.studyAdmin'),
valueGetter: (params) => params.row.isStudyAdmin,
renderCell: (params: GridRenderCellParams) => {
return (
@@ -152,7 +155,7 @@ const UserPermissionTable: React.FC<{ study: Study }> = ({ study }) => {
},
{
field: 'contributor',
- headerName: 'Contributor',
+ headerName: t('components.userPermissions.contributor'),
valueGetter: (params) => params.row.isContributor,
renderCell: (params: GridRenderCellParams) => {
return (
@@ -164,7 +167,7 @@ const UserPermissionTable: React.FC<{ study: Study }> = ({ study }) => {
},
{
field: 'trained',
- headerName: 'Trained',
+ headerName: t('components.userPermissions.trained'),
valueGetter: (params) => params.row.isTrained,
renderCell: (params: GridRenderCellParams) => {
return (