I'm attempting to create layout components for sections of my application which include side navigation panes for navigating between pages within that layout component.
I have react router set up using a BrowserRouter within my Main view. This main view includes the top navigation bar with a menu. When I click the Menu drop down, I can select a section of the app to browse to. This will open a layout which includes the side navigation bar. When a user clicks a link within the side nav bar, it should display content within a content pane on the right side of the screen.
For more info, please see the code example below:
https://codesandbox.io/s/compassionate-snowflake-eqzh0y
import * as React from "react";
import AppLayout from "@cloudscape-design/components/app-layout";
import BreadcrumbGroup from "@cloudscape-design/components/breadcrumb-group";
import Flashbar from "@cloudscape-design/components/flashbar";
import SideNavigation from "@cloudscape-design/components/side-navigation";
import SplitPanel from "@cloudscape-design/components/split-panel";
import TestDetails from "./TestDetails";
import TestTable from "./TestTable";
import { Route, Routes, useNavigate } from "react-router-dom";
function TestLayout() {
const [flashMessages, setFlashMessages] = React.useState(Array);
const [testDetails, setTestDetails] = React.useState("");
let navigate = useNavigate();
function handleSideNavigationItemClick(e) {
e.preventDefault();
console.log("Navigating to " + e.detail.href);
navigate(e.detail.href);
}
const showFlashMessage = (type, header, body) => {
let message = {
type: type,
dismissible: true,
dismissLabel: "Dismiss message",
header: header,
onDismiss: () =>
setFlashMessages((flashMessages) =>
flashMessages.filter((item) => item.id !== "flash_message_1")
),
content: <>{body}</>,
id: "flash_message_1"
};
setFlashMessages([...flashMessages, message]);
};
React.useEffect(() => {
setTestDetails("Some test details");
}, []);
return (
<React.Fragment>
<AppLayout
breadcrumbs={
<BreadcrumbGroup items={[{ text: "Test Main", href: "/testing" }]} />
}
content={
<Routes>
<Route
element={<TestTable showFlashMessage={showFlashMessage} />}
path="/testing/viewTests"
/>
<Route
element={
<TestDetails
details={testDetails}
showFlashMessage={showFlashMessage}
/>
}
path="/testing/viewTestDetails"
/>
</Routes>
}
contentType="table"
navigation={
<SideNavigation
header={{ href: "#/", text: "Testing" }}
items={[
{
type: "section",
text: "Tests",
items: [
{
type: "link",
text: "View Test Details",
href: "/testing/viewTestDetails"
},
{
type: "link",
text: "View All Tests",
href: "/testing/viewTests"
}
]
}
]}
onFollow={handleSideNavigationItemClick}
/>
}
notifications={<Flashbar items={flashMessages} />}
splitPanel={
<SplitPanel
header={"Test Info"}
i18nStrings={{
preferencesTitle: "Preferences",
preferencesPositionLabel: "Split panel position",
preferencesPositionDescription:
"Choose the default split panel position for the service.",
preferencesPositionSide: "Side",
preferencesPositionBottom: "Bottom",
preferencesConfirm: "Confirm",
preferencesCancel: "Cancel",
closeButtonAriaLabel: "Close panel",
openButtonAriaLabel: "Open panel",
resizeHandleAriaLabel: "Slider"
}}
>
Select a test from the table above to view more info
</SplitPanel>
}
stickyNotifications={true}
toolsHide={true}
/>
</React.Fragment>
);
}
export default TestLayout;
In the example above within the TestLayout component, I'm placing the routes in the content parameter in the AppLayout component to render when the page loads. When the click events in the side nav bar fire, it should navigate to the components I specify in those routes. Instead, when I click a link, the event fires, navigates to the new link, but no components are updated on the screen.
Also, the child components in the layout view share data from the parent layout component like functions for flash messages, state data, etc.
Is this the correct location for the routes to be placed? Should all of the routes only be stored in the index.js file in this example, and if so, how should data be passed to the child components?