From 508758a6e4ed3fee8246bd6e4ba98a50a13e6301 Mon Sep 17 00:00:00 2001 From: "D. Ror." Date: Tue, 8 Oct 2024 14:24:19 -0400 Subject: [PATCH] Replace deprecated Hidden component with useMediaQuery hook (#3246) --- src/components/App/tests/index.test.tsx | 10 +- src/components/AppBar/Logo.tsx | 18 +- src/components/AppBar/NavigationButtons.tsx | 15 +- src/components/AppBar/ProjectButtons.tsx | 31 ++-- src/components/AppBar/UserMenu.tsx | 23 ++- .../AppBar/tests/AppBarComponent.test.tsx | 14 +- src/components/AppBar/tests/Logo.test.tsx | 8 +- .../AppBar/tests/NavigationButtons.test.tsx | 11 +- .../AppBar/tests/ProjectButtons.test.tsx | 11 +- src/components/AppBar/tests/UserMenu.test.tsx | 10 +- src/components/LandingPage/TopBar.tsx | 22 ++- src/components/LandingPage/index.tsx | 50 +++--- src/components/ProjectScreen/index.tsx | 27 ++- .../ProjectScreen/tests/index.test.tsx | 8 +- src/components/ProjectSettings/index.tsx | 28 ++- .../ProjectSettings/tests/index.test.tsx | 20 ++- .../TreeView/TreeDepiction/index.tsx | 61 +++---- .../tests/__snapshots__/index.test.tsx.snap | 168 +++++++++--------- .../TreeDepiction/tests/index.test.tsx | 8 +- src/components/TreeView/index.tsx | 11 +- src/components/TreeView/tests/index.test.tsx | 12 +- src/utilities/testRendererUtilities.tsx | 3 +- 22 files changed, 305 insertions(+), 264 deletions(-) diff --git a/src/components/App/tests/index.test.tsx b/src/components/App/tests/index.test.tsx index de656201c8..4d427a8f79 100644 --- a/src/components/App/tests/index.test.tsx +++ b/src/components/App/tests/index.test.tsx @@ -1,3 +1,4 @@ +import { ThemeProvider } from "@mui/material/styles"; import { render } from "@testing-library/react"; import "jest-canvas-mock"; import { act } from "react"; @@ -7,6 +8,7 @@ import thunk from "redux-thunk"; import App from "components/App"; import { defaultState } from "rootRedux/types"; +import theme from "types/theme"; jest.mock("react-router-dom"); @@ -22,9 +24,11 @@ describe("App", () => { it("renders without crashing", async () => { await act(async () => { render( - - - + + + + + ); }); }); diff --git a/src/components/AppBar/Logo.tsx b/src/components/AppBar/Logo.tsx index ec5b9769a5..09164addde 100644 --- a/src/components/AppBar/Logo.tsx +++ b/src/components/AppBar/Logo.tsx @@ -1,4 +1,4 @@ -import { Button, Hidden } from "@mui/material"; +import { Button, Theme, useMediaQuery } from "@mui/material"; import { ReactElement } from "react"; import { useNavigate } from "react-router-dom"; @@ -10,6 +10,8 @@ import { themeColors } from "types/theme"; /** A button that redirects to the home page */ export default function Logo(): ReactElement { + const isSmDown = useMediaQuery((th) => th.breakpoints.down("sm")); + const isMdDown = useMediaQuery((th) => th.breakpoints.down("md")); const navigate = useNavigate(); return ( ); } diff --git a/src/components/AppBar/NavigationButtons.tsx b/src/components/AppBar/NavigationButtons.tsx index 39c5765840..56640c49fe 100644 --- a/src/components/AppBar/NavigationButtons.tsx +++ b/src/components/AppBar/NavigationButtons.tsx @@ -1,6 +1,12 @@ import { PlaylistAdd, Rule } from "@mui/icons-material"; -import { Button, Hidden, Tooltip, Typography } from "@mui/material"; -import { ReactElement, useEffect, useState } from "react"; +import { + Button, + type Theme, + Tooltip, + Typography, + useMediaQuery, +} from "@mui/material"; +import { type ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; @@ -71,6 +77,7 @@ function NavButton(props: NavButtonProps): ReactElement { const { t } = useTranslation(); const navigate = useNavigate(); const { windowWidth } = useWindowSize(); + const showText = useMediaQuery((th) => th.breakpoints.up("sm")); return ( ); } diff --git a/src/components/AppBar/ProjectButtons.tsx b/src/components/AppBar/ProjectButtons.tsx index af9293a686..4507ce2961 100644 --- a/src/components/AppBar/ProjectButtons.tsx +++ b/src/components/AppBar/ProjectButtons.tsx @@ -1,5 +1,11 @@ import { BarChart, Settings } from "@mui/icons-material"; -import { Button, Hidden, Tooltip, Typography } from "@mui/material"; +import { + Button, + Theme, + Tooltip, + Typography, + useMediaQuery, +} from "@mui/material"; import { ReactElement, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { useSelector } from "react-redux"; @@ -42,6 +48,15 @@ export default function ProjectButtons(props: TabProps): ReactElement { const { t } = useTranslation(); const navigate = useNavigate(); + const isMdUp = useMediaQuery((th) => th.breakpoints.up("md")); + const isLg = useMediaQuery((th) => th.breakpoints.only("lg")); + const isXl = useMediaQuery((th) => th.breakpoints.only("xl")); + const nameLength = isXl + ? projNameLength.xl + : isLg + ? projNameLength.lg + : projNameLength.md; + useEffect(() => { hasPermission(Permission.Statistics).then(setHasStatsPermission); }, []); @@ -77,22 +92,14 @@ export default function ProjectButtons(props: TabProps): ReactElement { }} > - + {isMdUp && ( - - {shortenName(projectName, projNameLength.xl)} - - - {shortenName(projectName, projNameLength.lg)} - - - {shortenName(projectName, projNameLength.md)} - + {shortenName(projectName, nameLength)} - + )} {showSpeaker && } diff --git a/src/components/AppBar/UserMenu.tsx b/src/components/AppBar/UserMenu.tsx index 429d5860e0..5cdbdcfd3a 100644 --- a/src/components/AppBar/UserMenu.tsx +++ b/src/components/AppBar/UserMenu.tsx @@ -7,15 +7,15 @@ import { import { Avatar, Button, - Hidden, Menu, MenuItem, + type Theme, Typography, + useMediaQuery, } from "@mui/material"; import { type CSSProperties, type ForwardedRef, - Fragment, type MouseEvent, type ReactElement, useState, @@ -53,6 +53,10 @@ export default function UserMenu(props: TabProps): ReactElement { const [isAdmin, setIsAdmin] = useState(false); const username = LocalStorage.getCurrentUser()?.username; + const isLgUp = useMediaQuery((th) => th.breakpoints.up("lg")); + const isXl = useMediaQuery((th) => th.breakpoints.only("xl")); + const nameLength = isXl ? usernameLength.xl : usernameLength.lg; + function handleClick(event: MouseEvent): void { setAnchorElement(event.currentTarget); } @@ -78,17 +82,10 @@ export default function UserMenu(props: TabProps): ReactElement { padding: 0, }} > - {username ? ( - - - {shortenName(username, usernameLength.xl)} - - {shortenName(username, usernameLength.lg)} - - - - ) : ( - + {!!username && isLgUp && ( + + {shortenName(username, nameLength)} + )} {avatar ? ( diff --git a/src/components/AppBar/tests/AppBarComponent.test.tsx b/src/components/AppBar/tests/AppBarComponent.test.tsx index a3c78dee6e..5d880ca1fe 100644 --- a/src/components/AppBar/tests/AppBarComponent.test.tsx +++ b/src/components/AppBar/tests/AppBarComponent.test.tsx @@ -1,3 +1,4 @@ +import { ThemeProvider } from "@mui/material/styles"; import { Provider } from "react-redux"; import { MemoryRouter } from "react-router-dom"; import { act, create } from "react-test-renderer"; @@ -5,6 +6,7 @@ import configureMockStore from "redux-mock-store"; import AppBar from "components/AppBar/AppBarComponent"; import { defaultState } from "rootRedux/types"; +import theme from "types/theme"; jest.mock("backend", () => ({ isSiteAdmin: () => mockIsSiteAdmin(), @@ -26,11 +28,13 @@ describe("AppBar", () => { it("renders", async () => { await act(async () => { create( - - - - - + + + + + + + ); }); }); diff --git a/src/components/AppBar/tests/Logo.test.tsx b/src/components/AppBar/tests/Logo.test.tsx index ba558672c4..90011be056 100644 --- a/src/components/AppBar/tests/Logo.test.tsx +++ b/src/components/AppBar/tests/Logo.test.tsx @@ -1,8 +1,10 @@ import { Button } from "@mui/material"; +import { ThemeProvider } from "@mui/material/styles"; import renderer from "react-test-renderer"; import Logo from "components/AppBar/Logo"; import { Path } from "types/path"; +import theme from "types/theme"; jest.mock("react-router-dom", () => ({ useNavigate: @@ -17,7 +19,11 @@ let testRenderer: renderer.ReactTestRenderer; beforeAll(() => { renderer.act(() => { - testRenderer = renderer.create(); + testRenderer = renderer.create( + + + + ); }); }); diff --git a/src/components/AppBar/tests/NavigationButtons.test.tsx b/src/components/AppBar/tests/NavigationButtons.test.tsx index 45d02e0f55..ac0b442af7 100644 --- a/src/components/AppBar/tests/NavigationButtons.test.tsx +++ b/src/components/AppBar/tests/NavigationButtons.test.tsx @@ -1,3 +1,4 @@ +import { ThemeProvider } from "@mui/material/styles"; import { Provider } from "react-redux"; import renderer, { type ReactTestInstance } from "react-test-renderer"; import configureMockStore from "redux-mock-store"; @@ -8,7 +9,7 @@ import NavigationButtons, { dataEntryButtonId, } from "components/AppBar/NavigationButtons"; import { Path } from "types/path"; -import { themeColors } from "types/theme"; +import theme, { themeColors } from "types/theme"; jest.mock("react-router-dom", () => ({ useNavigate: jest.fn(), @@ -34,9 +35,11 @@ const renderNavButtons = async ( mockGetCurrentPermissions.mockResolvedValue([permission]); await renderer.act(async () => { testRenderer = renderer.create( - - - + + + + + ); }); }; diff --git a/src/components/AppBar/tests/ProjectButtons.test.tsx b/src/components/AppBar/tests/ProjectButtons.test.tsx index b5ea3f7b36..cf66ae5343 100644 --- a/src/components/AppBar/tests/ProjectButtons.test.tsx +++ b/src/components/AppBar/tests/ProjectButtons.test.tsx @@ -1,4 +1,5 @@ import { Button } from "@mui/material"; +import { ThemeProvider } from "@mui/material/styles"; import { Provider } from "react-redux"; import { ReactTestRenderer, act, create } from "react-test-renderer"; import configureMockStore, { MockStoreEnhanced } from "redux-mock-store"; @@ -14,7 +15,7 @@ import { MergeDups } from "goals/MergeDuplicates/MergeDupsTypes"; import { ReviewEntries } from "goals/ReviewEntries/ReviewEntriesTypes"; import { Goal, GoalStatus } from "types/goals"; import { Path } from "types/path"; -import { themeColors } from "types/theme"; +import theme, { themeColors } from "types/theme"; jest.mock("react-router-dom", () => ({ useNavigate: jest.fn(), @@ -46,9 +47,11 @@ const renderProjectButtons = async ( ): Promise => { await act(async () => { testRenderer = create( - - - + + + + + ); }); }; diff --git a/src/components/AppBar/tests/UserMenu.test.tsx b/src/components/AppBar/tests/UserMenu.test.tsx index 853885fd5d..5fc178b73e 100644 --- a/src/components/AppBar/tests/UserMenu.test.tsx +++ b/src/components/AppBar/tests/UserMenu.test.tsx @@ -1,10 +1,12 @@ import { Button, MenuItem } from "@mui/material"; +import { ThemeProvider } from "@mui/material/styles"; import { Provider } from "react-redux"; import { act, create, ReactTestRenderer } from "react-test-renderer"; import configureMockStore from "redux-mock-store"; import UserMenu, { UserMenuList } from "components/AppBar/UserMenu"; import { Path } from "types/path"; +import theme from "types/theme"; jest.mock("backend", () => ({ isSiteAdmin: () => mockIsSiteAdmin(), @@ -37,9 +39,11 @@ describe("UserMenu", () => { it("renders", async () => { await act(async () => { testRenderer = create( - - - + + + + + ); }); expect(testRenderer.root.findAllByType(Button).length).toEqual(1); diff --git a/src/components/LandingPage/TopBar.tsx b/src/components/LandingPage/TopBar.tsx index 9b67e40819..f0ecd1eb84 100644 --- a/src/components/LandingPage/TopBar.tsx +++ b/src/components/LandingPage/TopBar.tsx @@ -1,4 +1,11 @@ -import { AppBar, Hidden, Stack, Toolbar, Typography } from "@mui/material"; +import { + AppBar, + Stack, + Theme, + Toolbar, + Typography, + useMediaQuery, +} from "@mui/material"; import { ReactElement } from "react"; import { useTranslation } from "react-i18next"; @@ -8,6 +15,8 @@ export const topBarHeight = 70; /** A bar shown at the top of the landing page. */ export default function TopBar(): ReactElement { + const showSubtitle = useMediaQuery((th) => th.breakpoints.up("sm")); + const isMdUp = useMediaQuery((th) => th.breakpoints.up("md")); const { t } = useTranslation(); return ( @@ -22,12 +31,11 @@ export default function TopBar(): ReactElement { style={{ width: "100%" }} > Logo - - {t("landingPage.subtitle")} - - - {t("landingPage.subtitle")} - + {showSubtitle && ( + + {t("landingPage.subtitle")} + + )} diff --git a/src/components/LandingPage/index.tsx b/src/components/LandingPage/index.tsx index 98c94533f1..f167ff75bf 100644 --- a/src/components/LandingPage/index.tsx +++ b/src/components/LandingPage/index.tsx @@ -1,4 +1,11 @@ -import { Box, Grid, Hidden, Stack, Typography } from "@mui/material"; +import { + Box, + Grid, + Stack, + Theme, + Typography, + useMediaQuery, +} from "@mui/material"; import { ReactElement, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; @@ -21,42 +28,31 @@ const heightBetweenBars = parseInt(theme.spacing(1)); export default function LandingPage(): ReactElement { + const isXs = useMediaQuery((th) => th.breakpoints.only("xs")); const navigate = useNavigate(); + useEffect(() => { // If there is an AnnouncementBanner and somebody enters the URL for // the LandingPage when displaying page without an AppBar, this // prevents banner misalignment. navigate(Path.Root); }, [navigate]); + + const maxBodyHeight = + heightBetweenBars - (isXs ? horizontalButtonsHeight : 0); + return ( <> - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/src/components/ProjectScreen/index.tsx b/src/components/ProjectScreen/index.tsx index cb9e57e928..287aebf0ea 100644 --- a/src/components/ProjectScreen/index.tsx +++ b/src/components/ProjectScreen/index.tsx @@ -1,4 +1,4 @@ -import { Hidden, Stack } from "@mui/material"; +import { Stack, Theme, useMediaQuery } from "@mui/material"; import { ReactElement, useEffect } from "react"; import { clearCurrentProject } from "components/Project/ProjectActions"; @@ -10,6 +10,8 @@ import { useAppDispatch } from "rootRedux/hooks"; /** Where users create a project or choose an existing one */ export default function ProjectScreen(): ReactElement { const dispatch = useAppDispatch(); + const isXs = useMediaQuery((th) => th.breakpoints.only("xs")); + /* Disable Data Entry, Data Cleanup, Project Settings until a project is selected or created. */ useEffect(() => { dispatch(clearCurrentProject()); @@ -17,19 +19,14 @@ export default function ProjectScreen(): ReactElement { }, [dispatch]); return ( - <> - - - - - - - - - - - - - + + + + ); } diff --git a/src/components/ProjectScreen/tests/index.test.tsx b/src/components/ProjectScreen/tests/index.test.tsx index 6fe5ffbd22..4df46944d6 100644 --- a/src/components/ProjectScreen/tests/index.test.tsx +++ b/src/components/ProjectScreen/tests/index.test.tsx @@ -1,6 +1,8 @@ +import { ThemeProvider } from "@mui/material/styles"; import renderer from "react-test-renderer"; import ProjectScreen from "components/ProjectScreen"; +import theme from "types/theme"; jest.mock("components/ProjectScreen/ChooseProject", () => "div"); jest.mock("components/ProjectScreen/CreateProject", () => "div"); @@ -12,7 +14,11 @@ const mockDispatch = jest.fn(); it("renders without crashing", () => { renderer.act(() => { - renderer.create(); + renderer.create( + + + + ); }); expect(mockDispatch).toHaveBeenCalledTimes(2); }); diff --git a/src/components/ProjectSettings/index.tsx b/src/components/ProjectSettings/index.tsx index fe8cc7d3c2..c21fa820fe 100644 --- a/src/components/ProjectSettings/index.tsx +++ b/src/components/ProjectSettings/index.tsx @@ -16,12 +16,13 @@ import { import { Box, Divider, - Hidden, Stack, Tab, Tabs, + type Theme, Tooltip, Typography, + useMediaQuery, } from "@mui/material"; import { type ReactElement, @@ -90,6 +91,7 @@ export default function ProjectSettingsComponent(): ReactElement { const project = useAppSelector( (state: StoreState) => state.currentProjectState.project ); + const hideLabels = useMediaQuery((th) => th.breakpoints.down("md")); const navigate = useNavigate(); const { t } = useTranslation(); @@ -139,23 +141,13 @@ export default function ProjectSettingsComponent(): ReactElement { - - - - - - + diff --git a/src/components/ProjectSettings/tests/index.test.tsx b/src/components/ProjectSettings/tests/index.test.tsx index 31138ed374..ef1ee8e3a4 100644 --- a/src/components/ProjectSettings/tests/index.test.tsx +++ b/src/components/ProjectSettings/tests/index.test.tsx @@ -1,3 +1,4 @@ +import { ThemeProvider } from "@mui/material/styles"; import { LocalizationProvider } from "@mui/x-date-pickers"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import "@testing-library/jest-dom"; @@ -20,6 +21,7 @@ import { whichTabs, } from "components/ProjectSettings/tests/SettingsTabTypes"; import { randomProject } from "types/project"; +import theme from "types/theme"; jest.mock("react-router-dom", () => ({ useNavigate: jest.fn(), @@ -62,9 +64,11 @@ const updateProjSettings = async (hasSchedule = false): Promise => { // This is accomplished by randomProject() in createMockStore(). render( - - - + + + + + ); }); @@ -88,16 +92,18 @@ const createMatchMedia = ( }; beforeAll(async () => { - // Required for the elements to show up + // Required (along with a `ThemeProvider`) for `useMediaQuery` to work window.matchMedia = createMatchMedia(window.innerWidth); resetMocks(); await act(async () => { render( - - - + + + + + ); }); diff --git a/src/components/TreeView/TreeDepiction/index.tsx b/src/components/TreeView/TreeDepiction/index.tsx index 74a4dafce3..60518b94dd 100644 --- a/src/components/TreeView/TreeDepiction/index.tsx +++ b/src/components/TreeView/TreeDepiction/index.tsx @@ -1,4 +1,4 @@ -import { Grid, Hidden } from "@mui/material"; +import { Grid, Theme, useMediaQuery } from "@mui/material"; import { ReactElement, useEffect, useState } from "react"; import ChildrenRow from "components/TreeView/TreeDepiction/ChildrenRow"; @@ -13,6 +13,8 @@ import { parent } from "resources/tree"; import { useWindowSize } from "utilities/useWindowSize"; export default function TreeDepiction(props: TreeDepictionProps): ReactElement { + const showTree = useMediaQuery((th) => th.breakpoints.up("sm")); + const [colWidth, setColWidth] = useState(0); const { windowWidth } = useWindowSize(); @@ -25,45 +27,36 @@ export default function TreeDepiction(props: TreeDepictionProps): ReactElement { return ( <> {/* Display parent domain, if available. */} - - {currentDomain.parent && ( - <> - - - - - - - - )} - + {showTree && currentDomain.parent && ( + <> + + + + + + + + )} {/* Display current domain and (if available) left and right brothers. */} - - - - - - + {/* Display subdomains, if available. */} - - - {currentDomain.children.length > 0 && ( - - )} - - + + {showTree && currentDomain.children.length > 0 && ( + + )} + ); } diff --git a/src/components/TreeView/TreeDepiction/tests/__snapshots__/index.test.tsx.snap b/src/components/TreeView/TreeDepiction/tests/__snapshots__/index.test.tsx.snap index 224caf1d8e..65f7bdfe9e 100644 --- a/src/components/TreeView/TreeDepiction/tests/__snapshots__/index.test.tsx.snap +++ b/src/components/TreeView/TreeDepiction/tests/__snapshots__/index.test.tsx.snap @@ -6,7 +6,7 @@ Array [ className="MuiGrid-root MuiGrid-item css-13i4rnv-MuiGrid-root" >