Skip to content

Commit

Permalink
Router: Fix Switch inside a SubRouteIndexRoute to allow a Stack in a …
Browse files Browse the repository at this point in the history
…Stack initial page
  • Loading branch information
nsams committed Aug 1, 2023
1 parent 05415db commit 0453c36
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-pugs-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/admin": patch
---

Router: Fix Switch inside a SubRouteIndexRoute to allow a Stack in a Stack initial page
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { SubRouteIndexRoute, useSubRoutePrefix } from "@comet/admin";
import { storiesOf } from "@storybook/react";
import * as React from "react";
import { Redirect, Route, Switch, useLocation } from "react-router";
import { Link } from "react-router-dom";

import { storyRouterDecorator } from "../../story-router.decorator";

function Cmp1() {
const urlPrefix = useSubRoutePrefix();
return (
<div>
<Switch>
<Route path={`${urlPrefix}/sub`}>
<p>Cmp1-Sub</p>
</Route>
<SubRouteIndexRoute>
<p>Cmp1-Index</p>
<Link to={`${urlPrefix}/sub`}>to-cmp1-sub</Link>
</SubRouteIndexRoute>
</Switch>
</div>
);
}

function Story() {
return (
<div>
<Switch>
<SubRouteIndexRoute>
<Cmp1 />
</SubRouteIndexRoute>
<Route path="/sub">Sub</Route>
</Switch>
</div>
);
}

function Path() {
const location = useLocation();
const [, rerender] = React.useState(0);
React.useEffect(() => {
const timer = setTimeout(() => {
rerender(new Date().getTime());
}, 1000);
return () => clearTimeout(timer);
}, []);
return <div>{location.pathname}</div>;
}

function App() {
return (
<>
<Path />
<Switch>
<Route exact path="/">
<Redirect to="/foo" />
</Route>
<Route path="/foo">
<Story />
</Route>
</Switch>
</>
);
}

storiesOf("@comet/admin/router", module)
.addDecorator(storyRouterDecorator())
.add("Subroute nested index", () => <App />);
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Stack, StackBreadcrumbs, StackLink, StackPage, StackSwitch } from "@comet/admin";
import { storiesOf } from "@storybook/react";
import * as React from "react";
import { Redirect, Route, Switch, useLocation } from "react-router";

import { storyRouterDecorator } from "../../story-router.decorator";

function Path() {
const location = useLocation();
const [, rerender] = React.useState(0);
React.useEffect(() => {
const timer = setTimeout(() => {
rerender(new Date().getTime());
}, 1000);
return () => clearTimeout(timer);
}, []);
return <div>{location.pathname}</div>;
}
function Page2() {
return (
<Stack topLevelTitle="Stack Nested">
<StackBreadcrumbs />
<StackSwitch>
<StackPage name="page1">
<StackLink payload="test" pageName="page2-2">
activate page2-2
</StackLink>
</StackPage>
<StackPage name="page2-2">page2</StackPage>
</StackSwitch>
</Stack>
);
}

function Story() {
return (
<>
<Path />
<Stack topLevelTitle="Stack">
<StackBreadcrumbs />
<StackSwitch>
<StackPage name="page1">
<Page2 />
</StackPage>
<StackPage name="page2">page2</StackPage>
</StackSwitch>
</Stack>
</>
);
}

function App() {
return (
<Switch>
<Route exact path="/">
<Redirect to="/foo" />
</Route>
<Route path="/foo">
<Story />
</Route>
</Switch>
);
}

storiesOf("@comet/admin/stack", module)
.addDecorator(storyRouterDecorator())
.add("Stack Nested On Initial Page", () => <App />);
52 changes: 52 additions & 0 deletions packages/admin/admin/src/router/SubRoute.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,55 @@ test("Route below Subroute", async () => {
fireEvent.click(rendered.getByText("Sub"));
expect(rendered.getByText("urlPrefix=/foo/sub")).toBeInTheDocument();
});

test("SubRouteIndexRoute nested Switch", async () => {
function Cmp1() {
const urlPrefix = useSubRoutePrefix();
return (
<>
<Switch>
<Route path={`${urlPrefix}/cmp1-sub`}>
<div>Cmp1 Sub</div>
</Route>
<SubRouteIndexRoute>
<div>
<Link to={`${urlPrefix}/cmp1-sub`}>Cmp1 SubLink</Link>
</div>
</SubRouteIndexRoute>
</Switch>
</>
);
}

function Story() {
const urlPrefix = useSubRoutePrefix();
return (
<>
<Switch>
<Route path={`${urlPrefix}/sub1`}>
<div>Sub1</div>
</Route>
<SubRouteIndexRoute>
<Cmp1 />
</SubRouteIndexRoute>
</Switch>
</>
);
}

const history = createMemoryHistory();

const rendered = render(
<MuiThemeProvider theme={createTheme()}>
<Router history={history}>
<Story />
</Router>
</MuiThemeProvider>,
);

fireEvent.click(rendered.getByText("Cmp1 SubLink"));

await waitFor(() => {
expect(rendered.getByText("Cmp1 Sub")).toBeInTheDocument();
});
});
8 changes: 6 additions & 2 deletions packages/admin/admin/src/router/SubRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export function SubRouteIndexRoute({ children }: { children: React.ReactNode })
const matchIndex = matchPath(location.pathname, { path: match.url, exact: true });
const routeProps = matchIndex ? { path: match.url, exact: true } : { path: urlPrefix };

return <Route {...routeProps}>{children}</Route>;
return (
<SubRoute path={`${urlPrefix}/index`}>
<Route {...routeProps}>{children}</Route>
</SubRoute>
);
}

export function SubRoute({ children, path }: { children: React.ReactNode; path: string }) {
Expand All @@ -32,7 +36,7 @@ export function useSubRoutePrefix() {
ret = routerContext.match.url;
}
} else {
ret = routerContext?.match.url || "";
ret = routerContext?.match?.url || "";
}
ret = ret.replace(/\/$/, ""); //remove trailing slash
return ret;
Expand Down
2 changes: 1 addition & 1 deletion packages/admin/admin/src/stack/Stack.nested.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { StackPage } from "./Page";
import { Stack } from "./Stack";
import { StackSwitch, StackSwitchApiContext } from "./Switch";

test("basic test", async () => {
test("StackNested basic test", async () => {
function Page1() {
const switchApi = React.useContext(StackSwitchApiContext);
return (
Expand Down

0 comments on commit 0453c36

Please sign in to comment.