From 5ee5cfafd7f72333ccbf86be986e5af9a026726f Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Mon, 9 Jun 2025 16:18:59 -0400 Subject: [PATCH 1/8] [ProjectSettings, SiteSettings] Migrate from deprecated Grid --- src/components/Dialogs/UploadImage.tsx | 38 ++-- src/components/Dialogs/ViewImageDialog.tsx | 20 +- .../ProjectSettings/BaseSettings.tsx | 18 +- .../ProjectSettings/ProjectAutocomplete.tsx | 51 +++--- .../ProjectSettings/ProjectDomains.tsx | 17 +- .../ProjectSettings/ProjectImport.tsx | 78 ++++---- .../ProjectSettings/ProjectLanguages.tsx | 173 ++++++++---------- .../ProjectSettings/ProjectName.tsx | 42 ++--- .../ProjectProtectedOverride.tsx | 51 +++--- .../ProjectSchedule/CalendarView.tsx | 14 +- .../ProjectSchedule/DateScheduleEdit.tsx | 46 +++-- .../ProjectSchedule/DateSelector.tsx | 72 ++++---- .../ProjectSettings/ProjectSchedule/index.tsx | 45 ++--- src/components/ProjectSettings/index.tsx | 1 + .../ProjectUsers/AddProjectUsers.tsx | 42 ++--- src/components/ProjectUsers/EmailInvite.tsx | 63 +++---- src/components/ProjectUsers/UserList.tsx | 5 +- src/components/SiteSettings/Banners.tsx | 43 ++--- .../ProjectUsersButtonWithConfirmation.tsx | 2 +- .../UserManagement/ConfirmDeletion.tsx | 100 ++++------ .../SiteSettings/UserManagement/UserList.tsx | 10 +- .../SiteSettings/UserManagement/index.tsx | 5 +- src/components/SiteSettings/index.tsx | 14 +- 23 files changed, 433 insertions(+), 517 deletions(-) diff --git a/src/components/Dialogs/UploadImage.tsx b/src/components/Dialogs/UploadImage.tsx index d12cf914b9..a624bdbb0c 100644 --- a/src/components/Dialogs/UploadImage.tsx +++ b/src/components/Dialogs/UploadImage.tsx @@ -1,4 +1,4 @@ -import { Grid, Typography } from "@mui/material"; +import { Grid2, Typography } from "@mui/material"; import { FormEvent, ReactElement, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -53,25 +53,23 @@ export default function ImageUpload(props: ImageUploadProps): ReactElement { {t("createProject.fileSelected", { val: filename })} )} - - - updateFile(file)} - accept="image/*" - > - {t("buttons.browse")} - - - - - {t("buttons.save")} - - - + + + updateFile(file)} + accept="image/*" + > + {t("buttons.browse")} + + + + {t("buttons.save")} + + ); } diff --git a/src/components/Dialogs/ViewImageDialog.tsx b/src/components/Dialogs/ViewImageDialog.tsx index 88e23b474d..98280e9a69 100644 --- a/src/components/Dialogs/ViewImageDialog.tsx +++ b/src/components/Dialogs/ViewImageDialog.tsx @@ -1,4 +1,4 @@ -import { Dialog, DialogContent, DialogTitle, Grid, Icon } from "@mui/material"; +import { Dialog, DialogContent, DialogTitle, Grid2, Icon } from "@mui/material"; import { ReactElement } from "react"; import { CloseButton, DeleteButtonWithDialog } from "components/Buttons"; @@ -39,16 +39,14 @@ export default function ViewImageDialog( - - - - - + + + ); diff --git a/src/components/ProjectSettings/BaseSettings.tsx b/src/components/ProjectSettings/BaseSettings.tsx index eba43e01d3..01b4dab253 100644 --- a/src/components/ProjectSettings/BaseSettings.tsx +++ b/src/components/ProjectSettings/BaseSettings.tsx @@ -3,7 +3,8 @@ import { Accordion, AccordionDetails, AccordionSummary, - Grid, + Box, + Stack, Typography, } from "@mui/material"; import { type ReactElement, type ReactNode } from "react"; @@ -15,6 +16,8 @@ interface BaseSettingsProps { icon: ReactNode; /** If maxWidth not specified, defaults to 700px. */ maxWidth?: string | number; + /** If minWidth not specified, defaults to Accordion's default. */ + minWidth?: string | number; /** Setting title (goes second in `AccordionSummary` after icon). */ title: ReactNode; } @@ -29,17 +32,14 @@ export default function BaseSettings(props: BaseSettingsProps): ReactElement { background: (theme) => theme.palette.background.default, border: (theme) => `1px solid ${theme.palette.divider}`, maxWidth: props.maxWidth || "700px", + minWidth: props.minWidth, }} > }> - - - {props.icon} - - - {props.title} - - + + {props.icon} + {props.title} + {props.body} diff --git a/src/components/ProjectSettings/ProjectAutocomplete.tsx b/src/components/ProjectSettings/ProjectAutocomplete.tsx index 5890af880f..0bf3cdd4c7 100644 --- a/src/components/ProjectSettings/ProjectAutocomplete.tsx +++ b/src/components/ProjectSettings/ProjectAutocomplete.tsx @@ -1,5 +1,5 @@ import { HelpOutline } from "@mui/icons-material"; -import { Grid, MenuItem, Select, Tooltip } from "@mui/material"; +import { MenuItem, Select, Stack, Tooltip } from "@mui/material"; import { type ReactElement } from "react"; import { useTranslation } from "react-i18next"; @@ -18,31 +18,28 @@ export default function ProjectAutocomplete( }; return ( - - - - - - - - - - + + + + + + + ); } diff --git a/src/components/ProjectSettings/ProjectDomains.tsx b/src/components/ProjectSettings/ProjectDomains.tsx index ead883e90c..a2a299c7e9 100644 --- a/src/components/ProjectSettings/ProjectDomains.tsx +++ b/src/components/ProjectSettings/ProjectDomains.tsx @@ -9,7 +9,7 @@ import { Dialog, DialogContent, DialogTitle, - Grid, + Grid2, IconButton, Stack, Typography, @@ -313,24 +313,29 @@ export function AddDomainDialog(props: AddDomainDialogProps): ReactElement { return ( - - {t("projectSettings.domains.add")} - + + {t("projectSettings.domains.add")} + +
submit()} + size="small" > t.palette.success.main }} /> + cancel()} + size="small" > t.palette.error.main }} /> - - +
+
+ diff --git a/src/components/ProjectSettings/ProjectImport.tsx b/src/components/ProjectSettings/ProjectImport.tsx index a5144bbc0d..dd7fa02653 100644 --- a/src/components/ProjectSettings/ProjectImport.tsx +++ b/src/components/ProjectSettings/ProjectImport.tsx @@ -1,4 +1,4 @@ -import { Grid, Typography } from "@mui/material"; +import { Grid2, Typography } from "@mui/material"; import { type ReactElement, useEffect, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; import { toast } from "react-toastify"; @@ -75,8 +75,8 @@ export default function ProjectImport( }; return ( - - + + {t("projectSettings.import.body")}{" "} @@ -87,47 +87,41 @@ export default function ProjectImport( FillerTextC - + - - {/* Choose file button */} - - {t("projectSettings.import.chooseFile")} - - + {/* Choose file button */} + + {t("projectSettings.import.chooseFile")} + - - {/* Upload button */} - - {t("buttons.upload")} - - + {/* Upload button */} + + {t("buttons.upload")} + - - {/* Displays the name of the selected file */} - {liftFile && ( - - {t("createProject.fileSelected", { val: liftFile.name })} - - )} - + {/* Displays the name of the selected file */} + {liftFile && ( + + {t("createProject.fileSelected", { val: liftFile.name })} + + )} {liftLangs && ( )} - + ); } diff --git a/src/components/ProjectSettings/ProjectLanguages.tsx b/src/components/ProjectSettings/ProjectLanguages.tsx index e73b576c9a..1136da6b52 100644 --- a/src/components/ProjectSettings/ProjectLanguages.tsx +++ b/src/components/ProjectSettings/ProjectLanguages.tsx @@ -9,11 +9,12 @@ import { } from "@mui/icons-material"; import { Button, - Grid, + Grid2, IconButton, MenuItem, Select, SelectChangeEvent, + Stack, Typography, } from "@mui/material"; import { LanguagePicker, languagePickerStrings_en } from "mui-language-picker"; @@ -192,50 +193,46 @@ export default function ProjectLanguages( ); const addAnalysisLangPicker = (): ReactElement => ( - - - - setNewLang((prev: WritingSystem) => ({ ...prev, bcp47 })) - } - name={newLang.name} - setName={(name: string) => - setNewLang((prev: WritingSystem) => ({ ...prev, name })) - } - font={newLang.font} - setFont={(font: string) => - setNewLang((prev: WritingSystem) => ({ ...prev, font })) - } - setDir={(rtl: boolean) => - setNewLang((prev: WritingSystem) => ({ - ...prev, - rtl: rtl || undefined, - })) - } - t={languagePickerStrings_en} - /> - {" "} - - addAnalysisWritingSystem()} - id={ProjectLanguagesId.ButtonAddAnalysisLangConfirm} - size="large" - > - - - {" "} - - resetState()} - id={ProjectLanguagesId.ButtonAddAnalysisLangClear} - size="large" - > - - - - + + + setNewLang((prev: WritingSystem) => ({ ...prev, bcp47 })) + } + name={newLang.name} + setName={(name: string) => + setNewLang((prev: WritingSystem) => ({ ...prev, name })) + } + font={newLang.font} + setFont={(font: string) => + setNewLang((prev: WritingSystem) => ({ ...prev, font })) + } + setDir={(rtl: boolean) => + setNewLang((prev: WritingSystem) => ({ + ...prev, + rtl: rtl || undefined, + })) + } + t={languagePickerStrings_en} + /> + + addAnalysisWritingSystem()} + id={ProjectLanguagesId.ButtonAddAnalysisLangConfirm} + size="large" + > + + + + resetState()} + id={ProjectLanguagesId.ButtonAddAnalysisLangClear} + size="large" + > + + + ); const vernacularLanguageDisplay = (): ReactElement => ( @@ -258,32 +255,28 @@ export default function ProjectLanguages( ); const vernacularLanguageEditor = (): ReactElement => ( - - - setNewVernName(e.target.value)} - onBlur={() => { - setChangeVernName(false); - setNewVernName(props.project.vernacularWritingSystem.name); - }} - autoFocus - /> - - - - - + + setNewVernName(e.target.value)} + onBlur={() => { + setChangeVernName(false); + setNewVernName(props.project.vernacularWritingSystem.name); + }} + autoFocus + /> + + + ); return ( @@ -328,30 +321,22 @@ function ImmutableWritingSystem( ): ReactElement { const { t } = useTranslation(); + const number = props.index === undefined ? "" : `${props.index + 1}. `; + const wsText: string[] = []; + if (props.ws.name) { + wsText.push(`${t("projectSettings.language.name")}: ${props.ws.name}`); + } + wsText.push(`${t("projectSettings.language.bcp47")}: ${props.ws.bcp47}`); + if (props.ws.font) { + wsText.push(`${t("projectSettings.language.font")}: ${props.ws.font}`); + } + const text = number + wsText.join(", "); + return ( - - {props.index !== undefined && ( - - {`${props.index + 1}. `} - - )} - - {!!props.ws.name && ( - - {`${t("projectSettings.language.name")}: ${props.ws.name}, `} - - )} - - {`${t("projectSettings.language.bcp47")}: ${props.ws.bcp47}`} - - {!!props.ws.font && ( - - {`, ${t("projectSettings.language.font")}: ${props.ws.font}`} - - )} - - {props.buttons} - + + {text} + {props.buttons} + ); } diff --git a/src/components/ProjectSettings/ProjectName.tsx b/src/components/ProjectSettings/ProjectName.tsx index 8db9c8e742..5dbb15b998 100644 --- a/src/components/ProjectSettings/ProjectName.tsx +++ b/src/components/ProjectSettings/ProjectName.tsx @@ -1,4 +1,4 @@ -import { Button, Grid } from "@mui/material"; +import { Button, Stack } from "@mui/material"; import { type ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "react-toastify"; @@ -24,27 +24,23 @@ export default function ProjectName(props: ProjectSettingProps): ReactElement { }; return ( - - - setProjName(e.target.value)} - onBlur={() => setProjName(props.project.name)} - /> - - - - - + + setProjName(e.target.value)} + onBlur={() => setProjName(props.project.name)} + /> + + ); } diff --git a/src/components/ProjectSettings/ProjectProtectedOverride.tsx b/src/components/ProjectSettings/ProjectProtectedOverride.tsx index 89b03f82b9..297b84d982 100644 --- a/src/components/ProjectSettings/ProjectProtectedOverride.tsx +++ b/src/components/ProjectSettings/ProjectProtectedOverride.tsx @@ -1,5 +1,5 @@ import { HelpOutline } from "@mui/icons-material"; -import { Grid, MenuItem, Select, Tooltip } from "@mui/material"; +import { MenuItem, Select, Stack, Tooltip } from "@mui/material"; import { type ReactElement } from "react"; import { useTranslation } from "react-i18next"; @@ -18,31 +18,28 @@ export default function ProjectProtectedOverride( }; return ( - - - - - - - - - - + + + + + + + ); } diff --git a/src/components/ProjectSettings/ProjectSchedule/CalendarView.tsx b/src/components/ProjectSettings/ProjectSchedule/CalendarView.tsx index ed4aa71930..20ac40bdeb 100644 --- a/src/components/ProjectSettings/ProjectSchedule/CalendarView.tsx +++ b/src/components/ProjectSettings/ProjectSchedule/CalendarView.tsx @@ -1,4 +1,4 @@ -import { Icon } from "@mui/material"; +import { Grid2, Icon } from "@mui/material"; import { DateCalendar } from "@mui/x-date-pickers"; import dayjs, { Dayjs } from "dayjs"; import { ReactElement } from "react"; @@ -40,5 +40,15 @@ export default function CalendarView(props: CalendarViewProps): ReactElement { return Array.from(new Set(months)).sort().map(dayjs); } - return <>{handleCalendarView(getScheduledMonths(props.projectSchedule))}; + return ( + + {handleCalendarView(getScheduledMonths(props.projectSchedule))} + + ); } diff --git a/src/components/ProjectSettings/ProjectSchedule/DateScheduleEdit.tsx b/src/components/ProjectSettings/ProjectSchedule/DateScheduleEdit.tsx index 1ea9e8cc65..52ace6c37f 100644 --- a/src/components/ProjectSettings/ProjectSchedule/DateScheduleEdit.tsx +++ b/src/components/ProjectSettings/ProjectSchedule/DateScheduleEdit.tsx @@ -1,4 +1,4 @@ -import { Button, Grid } from "@mui/material"; +import { Button, Stack } from "@mui/material"; import { DateCalendar } from "@mui/x-date-pickers"; import dayjs, { Dayjs } from "dayjs"; import { ReactElement, useState } from "react"; @@ -57,7 +57,7 @@ export default function DateScheduleEdit( } return ( - <> + - - - - - - - {t("buttons.confirm")} - - - - + + + + + + {t("buttons.confirm")} + + + ); } diff --git a/src/components/ProjectSettings/ProjectSchedule/DateSelector.tsx b/src/components/ProjectSettings/ProjectSchedule/DateSelector.tsx index 212c4ad9cb..a230c2a12b 100644 --- a/src/components/ProjectSettings/ProjectSchedule/DateSelector.tsx +++ b/src/components/ProjectSettings/ProjectSchedule/DateSelector.tsx @@ -1,4 +1,4 @@ -import { Button, Grid } from "@mui/material"; +import { Button, Stack } from "@mui/material"; import { DatePicker } from "@mui/x-date-pickers/DatePicker"; import { Dayjs } from "dayjs"; import { enqueueSnackbar } from "notistack"; @@ -60,40 +60,40 @@ export default function DateSelector(props: DateSelectorProps): ReactElement { } return ( - <> - setStartDate(newValue)} - /> -    - setEndDate(newValue)} - /> - - - - - - handleSubmit(), - }} - > - {t("buttons.confirm")} - - - - + + + setStartDate(newValue)} + /> + + setEndDate(newValue)} + /> + + + + + + handleSubmit(), + }} + > + {t("buttons.confirm")} + + + ); } diff --git a/src/components/ProjectSettings/ProjectSchedule/index.tsx b/src/components/ProjectSettings/ProjectSchedule/index.tsx index aa83497be6..46e1cbd05a 100644 --- a/src/components/ProjectSettings/ProjectSchedule/index.tsx +++ b/src/components/ProjectSettings/ProjectSchedule/index.tsx @@ -1,5 +1,5 @@ import { CalendarMonth, DateRange, EventRepeat } from "@mui/icons-material"; -import { Button, Grid, Typography } from "@mui/material"; +import { Button, Grid2, Typography } from "@mui/material"; import { type ReactElement, useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import Modal from "react-modal"; @@ -57,21 +57,14 @@ export default function ProjectSchedule( return ( <> - + {!props.readOnly && ( - } @@ -91,19 +84,11 @@ export default function ProjectSchedule( onClick={() => setShowRemove(true)} buttonId={"Project-Schedule-removeDays"} /> - + )} - - - - + + + {t("projectSettings.schedule.removeAll")} - - + + - - + + - - + + ); diff --git a/src/components/ProjectSettings/index.tsx b/src/components/ProjectSettings/index.tsx index 92d36342f9..2653dc2195 100644 --- a/src/components/ProjectSettings/index.tsx +++ b/src/components/ProjectSettings/index.tsx @@ -305,6 +305,7 @@ export default function ProjectSettingsComponent(): ReactElement { /> } maxWidth="1050px" // Comfortably fits three months + minWidth="300px" // Ensures space for one month /> diff --git a/src/components/ProjectUsers/AddProjectUsers.tsx b/src/components/ProjectUsers/AddProjectUsers.tsx index 1f04640c28..776450a66f 100644 --- a/src/components/ProjectUsers/AddProjectUsers.tsx +++ b/src/components/ProjectUsers/AddProjectUsers.tsx @@ -1,4 +1,4 @@ -import { Button, Grid, Typography } from "@mui/material"; +import { Button, Stack, Typography } from "@mui/material"; import { ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import Modal from "react-modal"; @@ -59,31 +59,25 @@ export default function AddProjectUsers( } return ( - <> - - - + + {RuntimeConfig.getInstance().emailServicesEnabled() && ( - - - {t("projectSettings.invite.or")} - + <> + {t("projectSettings.invite.or")} - - - - + + )} {RuntimeConfig.getInstance().emailServicesEnabled() && ( @@ -99,6 +93,6 @@ export default function AddProjectUsers( /> )} - + ); } diff --git a/src/components/ProjectUsers/EmailInvite.tsx b/src/components/ProjectUsers/EmailInvite.tsx index b3128a3a9e..4ec3426c8e 100644 --- a/src/components/ProjectUsers/EmailInvite.tsx +++ b/src/components/ProjectUsers/EmailInvite.tsx @@ -1,4 +1,4 @@ -import { Card, CardContent, Grid, Typography } from "@mui/material"; +import { Box, Grid2, Stack, Typography } from "@mui/material"; import { ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "react-toastify"; @@ -47,48 +47,45 @@ export default function EmailInvite(props: InviteProps): ReactElement { }, [email]); return ( - - - + + + {t("projectSettings.invite.inviteByEmailLabel")} + setEmail(e.target.value)} - variant="outlined" - style={{ width: "100%" }} - margin="normal" - autoFocus - inputProps={{ maxLength: 100 }} + required + slotProps={{ htmlInput: { maxLength: 320 } }} /> + setMessage(e.target.value)} - variant="outlined" - style={{ width: "100%" }} - margin="normal" + slotProps={{ htmlInput: { maxLength: 10000 } }} /> - - - onSubmit(), - variant: "contained", - color: "primary", - }} - > - {t("buttons.invite")} - - - - - + + + onSubmit(), + variant: "contained", + }} + > + {t("buttons.invite")} + + + + ); } diff --git a/src/components/ProjectUsers/UserList.tsx b/src/components/ProjectUsers/UserList.tsx index a964ba804f..c9b46e7e69 100644 --- a/src/components/ProjectUsers/UserList.tsx +++ b/src/components/ProjectUsers/UserList.tsx @@ -2,7 +2,6 @@ import { Done } from "@mui/icons-material"; import { Avatar, Button, - Grid, List, ListItem, ListItemIcon, @@ -113,7 +112,7 @@ export default function UserList(props: UserListProps): ReactElement { }; return ( - +
{t("projectSettings.invite.searchTitle")} updateUsers(e.target.value)} @@ -124,6 +123,6 @@ export default function UserList(props: UserListProps): ReactElement { {filteredProjUsers.map(projUserListItem)} {filteredNonProjUsers.map(nonProjUserListItem)} - +
); } diff --git a/src/components/SiteSettings/Banners.tsx b/src/components/SiteSettings/Banners.tsx index 4b8090d228..f318fb4fcb 100644 --- a/src/components/SiteSettings/Banners.tsx +++ b/src/components/SiteSettings/Banners.tsx @@ -1,4 +1,4 @@ -import { Button, Grid } from "@mui/material"; +import { Button, Stack } from "@mui/material"; import { ChangeEvent, ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -9,11 +9,11 @@ import { NormalizedTextField } from "utilities/fontComponents"; export default function Banners(): ReactElement { return ( - <> + {[BannerType.Announcement, BannerType.Login].map((type) => ( ))} - + ); } @@ -57,26 +57,19 @@ function Banner(props: BannerProps): ReactElement { }; return ( - - - - + + - + - - - - + + ); } diff --git a/src/components/SiteSettings/ProjectManagement/ProjectUsersButtonWithConfirmation.tsx b/src/components/SiteSettings/ProjectManagement/ProjectUsersButtonWithConfirmation.tsx index 509e47e5ed..2de2991843 100644 --- a/src/components/SiteSettings/ProjectManagement/ProjectUsersButtonWithConfirmation.tsx +++ b/src/components/SiteSettings/ProjectManagement/ProjectUsersButtonWithConfirmation.tsx @@ -39,7 +39,7 @@ export default function ProjectUsersButtonWithConfirmation( {t("siteSettings.projectRoles")} setOpen(false)} open={open}> - + {t("siteSettings.projectRoles")} setOpen(false)} /> diff --git a/src/components/SiteSettings/UserManagement/ConfirmDeletion.tsx b/src/components/SiteSettings/UserManagement/ConfirmDeletion.tsx index 69d2a58040..639e9657b4 100644 --- a/src/components/SiteSettings/UserManagement/ConfirmDeletion.tsx +++ b/src/components/SiteSettings/UserManagement/ConfirmDeletion.tsx @@ -1,11 +1,4 @@ -import { - Button, - Grid, - Typography, - CardContent, - Card, - CardActions, -} from "@mui/material"; +import { Box, Button, Stack, Typography } from "@mui/material"; import { Fragment, ReactElement } from "react"; import { useTranslation } from "react-i18next"; @@ -26,63 +19,44 @@ export default function ConfirmDeletion( return ; } return ( - <> - - - - - {props.user.username} + + + + {props.user.username} + + + + {t("siteSettings.deleteUser.confirm")} + + + + + + - - - - -
- - - - + + + + ); } diff --git a/src/components/SiteSettings/UserManagement/UserList.tsx b/src/components/SiteSettings/UserManagement/UserList.tsx index 300c42da7c..24b11dfb52 100644 --- a/src/components/SiteSettings/UserManagement/UserList.tsx +++ b/src/components/SiteSettings/UserManagement/UserList.tsx @@ -2,13 +2,13 @@ import { DeleteForever, VpnKey } from "@mui/icons-material"; import { Avatar, Button, - Grid, List, ListItem, ListItemAvatar, ListItemIcon, ListItemText, SelectChangeEvent, + Stack, Typography, } from "@mui/material"; import { ReactElement, useCallback, useEffect, useState } from "react"; @@ -101,9 +101,9 @@ export default function UserList(props: UserListProps): ReactElement { }; return ( - + <> {t("projectSettings.invite.searchTitle")} - + setFilterInput(e.target.value)} placeholder={t("projectSettings.invite.searchPlaceholder")} @@ -116,8 +116,8 @@ export default function UserList(props: UserListProps): ReactElement { } onReverseClick={() => setReverseSorting(!reverseSorting)} /> - + {sortedUsers.map(userListItem)} - + ); } diff --git a/src/components/SiteSettings/UserManagement/index.tsx b/src/components/SiteSettings/UserManagement/index.tsx index bfff55a4c7..0a5a12dec2 100644 --- a/src/components/SiteSettings/UserManagement/index.tsx +++ b/src/components/SiteSettings/UserManagement/index.tsx @@ -1,4 +1,3 @@ -import { Grid } from "@mui/material"; import { ReactElement, useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import Modal from "react-modal"; @@ -67,9 +66,7 @@ export default function UserManagement(): ReactElement { return ( <> - - - + + {t("siteSettings.projectList")} - + } value={SiteSettingsTab.Projects} /> @@ -45,10 +45,10 @@ export default function SiteSettings(): ReactElement { data-testid={SiteSettingsTab.Users} id={SiteSettingsTab.Users.toString()} label={ - + {t("siteSettings.userList")} - + } value={SiteSettingsTab.Users} /> @@ -56,10 +56,10 @@ export default function SiteSettings(): ReactElement { data-testid={SiteSettingsTab.Banners} id={SiteSettingsTab.Banners.toString()} label={ - + {t("siteSettings.banners.title")} - + } value={SiteSettingsTab.Banners} /> From b739bfa1c9a9978ab11d271d492eed07be48cce2 Mon Sep 17 00:00:00 2001 From: Danny Rorabaugh Date: Mon, 9 Jun 2025 17:45:36 -0400 Subject: [PATCH 2/8] Refine --- public/locales/en/translation.json | 1 + .../ProjectSettings/BaseSettings.tsx | 18 +++++--- .../ProjectSettings/ProjectLanguages.tsx | 2 +- .../ProjectSchedule/CalendarView.tsx | 8 +--- .../ProjectSettings/ProjectSchedule/index.tsx | 25 ++++------- src/components/ProjectSettings/index.tsx | 13 ++++-- src/components/SiteSettings/Banners.tsx | 7 ++-- src/components/SiteSettings/index.tsx | 42 ++++++++++++------- 8 files changed, 64 insertions(+), 52 deletions(-) diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 20850a277f..20c7d05c70 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -286,6 +286,7 @@ "searchPlaceholder": "Search...", "searchTitle": "Find Users", "emailLabel": "Email", + "emailMessage": "Message (optional)", "toastSuccess": "User added to the project.", "toastFail": "Failed to add user to the project." }, diff --git a/src/components/ProjectSettings/BaseSettings.tsx b/src/components/ProjectSettings/BaseSettings.tsx index 01b4dab253..6b3a8c3748 100644 --- a/src/components/ProjectSettings/BaseSettings.tsx +++ b/src/components/ProjectSettings/BaseSettings.tsx @@ -4,7 +4,6 @@ import { AccordionDetails, AccordionSummary, Box, - Stack, Typography, } from "@mui/material"; import { type ReactElement, type ReactNode } from "react"; @@ -36,10 +35,19 @@ export default function BaseSettings(props: BaseSettingsProps): ReactElement { }} > }> - - {props.icon} - {props.title} - + + + {props.icon} + + {props.title} + {props.body} diff --git a/src/components/ProjectSettings/ProjectLanguages.tsx b/src/components/ProjectSettings/ProjectLanguages.tsx index 1136da6b52..871c334634 100644 --- a/src/components/ProjectSettings/ProjectLanguages.tsx +++ b/src/components/ProjectSettings/ProjectLanguages.tsx @@ -255,7 +255,7 @@ export default function ProjectLanguages( ); const vernacularLanguageEditor = (): ReactElement => ( - + + {handleCalendarView(getScheduledMonths(props.projectSchedule))} ); diff --git a/src/components/ProjectSettings/ProjectSchedule/index.tsx b/src/components/ProjectSettings/ProjectSchedule/index.tsx index 46e1cbd05a..069dd4aac1 100644 --- a/src/components/ProjectSettings/ProjectSchedule/index.tsx +++ b/src/components/ProjectSettings/ProjectSchedule/index.tsx @@ -1,5 +1,5 @@ import { CalendarMonth, DateRange, EventRepeat } from "@mui/icons-material"; -import { Button, Grid2, Typography } from "@mui/material"; +import { Button, Grid2, Stack, Typography } from "@mui/material"; import { type ReactElement, useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import Modal from "react-modal"; @@ -57,15 +57,9 @@ export default function ProjectSchedule( return ( <> - + {!props.readOnly && ( - + } textId="projectSettings.schedule.setDays" @@ -121,10 +115,10 @@ export default function ProjectSchedule( shouldCloseOnOverlayClick={false} onRequestClose={() => setShowRemove(false)} > - {t("projectSettings.schedule.removeAll")} + + {t("projectSettings.schedule.removeAll")} - - + - - + - - + + ); diff --git a/src/components/ProjectSettings/index.tsx b/src/components/ProjectSettings/index.tsx index 2653dc2195..fe22e62924 100644 --- a/src/components/ProjectSettings/index.tsx +++ b/src/components/ProjectSettings/index.tsx @@ -474,10 +474,15 @@ function TabLabel(props: TabLabelProps): ReactElement { return props.hideLabel ? ( {props.icon} ) : ( - - {props.icon} - {t(props.textId)} - + + + {props.icon} + + {t(props.textId)} + ); } diff --git a/src/components/SiteSettings/Banners.tsx b/src/components/SiteSettings/Banners.tsx index f318fb4fcb..6fa2591e01 100644 --- a/src/components/SiteSettings/Banners.tsx +++ b/src/components/SiteSettings/Banners.tsx @@ -4,12 +4,11 @@ import { useTranslation } from "react-i18next"; import { BannerType } from "api/models"; import { getBannerText, updateBanner } from "backend"; -import theme from "types/theme"; import { NormalizedTextField } from "utilities/fontComponents"; export default function Banners(): ReactElement { return ( - + {[BannerType.Announcement, BannerType.Login].map((type) => ( ))} @@ -57,7 +56,7 @@ function Banner(props: BannerProps): ReactElement { }; return ( - + - + - - )} + + + )} + {RuntimeConfig.getInstance().emailServicesEnabled() && ( )} - + ); }