I have a React app that uses the Material UI Toolpad Dashboard layout. The left navigation bar contains the main navigation pages. Those work correctly. There are other pages that I want to navigate to using a Select dropdown in the PageLayout toolbar. That doesn't work.
I created a sandbox that shows what I mean. You'll see two icons on the left panel. Default is Home. You'll see a Select box in the toolbar. I don't want that toolbar to show when on the home page, only the others.
If you click the human icon, it will go to the Physiology page. If you click the dropdown, you'll see two options, Physiology and Anatomy. If you select Anatomy, the PageContainer toolbar with the page title and breadcrumbs is gone, and it has not navigated to the Anatomy page.
I've wasted so much time on this I've finally given up and am asking you experts for help!
I have a React app that uses the Material UI Toolpad Dashboard layout. The left navigation bar contains the main navigation pages. Those work correctly. There are other pages that I want to navigate to using a Select dropdown in the PageLayout toolbar. That doesn't work.
I created a sandbox that shows what I mean. You'll see two icons on the left panel. Default is Home. You'll see a Select box in the toolbar. I don't want that toolbar to show when on the home page, only the others.
If you click the human icon, it will go to the Physiology page. If you click the dropdown, you'll see two options, Physiology and Anatomy. If you select Anatomy, the PageContainer toolbar with the page title and breadcrumbs is gone, and it has not navigated to the Anatomy page.
I've wasted so much time on this I've finally given up and am asking you experts for help!
Share Improve this question asked Mar 28 at 16:42 flyskiflyski 333 bronze badges 1- I suspect what I'm asking for is impossible with the Toolpad Dashboard structure. Any page you want to navigate to must be under the AppProvider umbrella, which provides the page title and breadcrumbs. But that produces a left navigation page that is way too big for the hundreds of pages I have. Looks like I'm going to have to create my own solution. – flyski Commented Mar 29 at 15:03
1 Answer
Reset to default 1PageSelector.tsx
I've used useMemo to change the option depends of the location you are. Delete the + "/" + and defined a property called href to navigate correctly, use replace true to avoid append the route.
import { useEffect, useState, useMemo } from "react";
import { useNavigate, useLocation } from "react-router";
import FormControl from "@mui/material/FormControl";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
export default function PageSelector(props: any) {
const navigate = useNavigate();
const location = useLocation();
const [selectedOption, setSelectedOption] = useState<string>("physiology");
const options = useMemo(() => {
const { pathname } = location;
const optionSelected =
pathname == "/" ? "physiology" : pathname?.split("/")[1];
return categoryOptions[optionSelected];
}, [location, categoryOptions]);
return (
<FormControl sx={{ minWidth: 120 }}>
<InputLabel id="label">{options[selectedOption]}</InputLabel>
<Select
labelId="label"
value={selectedOption}
onChange={(e: SelectChangeEvent) => setSelectedOption(e.target.value)}
sx={{ minWidth: 175 }}
>
{options.map((option: any) => (
<MenuItem
key={option.value}
value={option.value}
onClick={() => navigate(option.href, { replace: true })}
>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
);
}
interface CategoryOption {
key: string;
value: string;
label: string;
href: string;
}
var categoryOptions: { [key: string]: CategoryOption[] } = {};
categoryOptions["physiology"] = [
{
key: "physiology",
value: "physiology",
label: "Physiology",
href: "physiology",
},
{ key: "anatomy", value: "anatomy", label: "Anatomy", href: "anatomy" },
];
categoryOptions["anatomy"] = [
{ key: "anatomy", value: "anatomy", label: "Anatomy", href: "anatomy" },
{
key: "physiology",
value: "physiology",
label: "Physiology",
href: "physiology",
},
{ key: "cells", value: "cells", label: "Cells", href: "anatomy/cells" },
{
key: "tissues",
value: "tissues",
label: "Tissues",
href: "anatomy/tissues",
},
];
main.tsx
In this file I added the other routes of the app, you must define all route of your app, in this case I used the contact-page as Component of the "anatomy/cells" route.
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router";
import App from "./App";
import Layout from "./layouts/dashboard";
import HomePage from "./pages";
import PhysiologyPage from "./pages/physiology";
import AboutPage from "./pages/about";
import ContactPage from "./pages/contact";
import AnatomyPage from "./pages/physiology";
//...
const router = createBrowserRouter([
{
Component: App, // root layout route
children: [
{
path: "/",
Component: Layout,
children: [
{
path: "",
Component: HomePage,
},
{
path: "physiology",
Component: PhysiologyPage,
},
{
path: "physiology/anatomy",
Component: AnatomyPage,
},
{
path: "about",
Component: AboutPage,
},
{
path: "about/contact",
Component: ContactPage,
},
{
path: "anatomy",
Component: AnatomyPage,
},
{
path: "anatomy/cells", // ADDED
Component: ContactPage,
},
],
},
],
},
]);
ReactDOM.createRoot(document.getElementById("root")!).render(
<RouterProvider router={router} />
);