Skip to content

Commit 4c7132f

Browse files
authored
chore: redirect to the correct template page routes (#14230)
1 parent 59a80d7 commit 4c7132f

File tree

3 files changed

+115
-19
lines changed

3 files changed

+115
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { waitFor } from "@testing-library/react";
2+
import { API } from "api/api";
3+
import * as M from "testHelpers/entities";
4+
import { renderWithAuth } from "testHelpers/renderHelpers";
5+
import { TemplateRedirectController } from "./TemplateRedirectController";
6+
7+
const renderTemplateRedirectController = (route: string) => {
8+
return renderWithAuth(<TemplateRedirectController />, {
9+
route,
10+
path: "/templates/:organization?/:template",
11+
});
12+
};
13+
14+
it("redirects from multi-org to single-org", async () => {
15+
const { router } = renderTemplateRedirectController(
16+
`/templates/${M.MockTemplate.organization_name}/${M.MockTemplate.name}`,
17+
);
18+
19+
await waitFor(() =>
20+
expect(router.state.location.pathname).toEqual(
21+
`/templates/${M.MockTemplate.name}`,
22+
),
23+
);
24+
});
25+
26+
it("redirects from single-org to multi-org", async () => {
27+
jest
28+
.spyOn(API, "getOrganizations")
29+
.mockResolvedValueOnce([M.MockDefaultOrganization, M.MockOrganization2]);
30+
31+
const { router } = renderTemplateRedirectController(
32+
`/templates/${M.MockTemplate.name}`,
33+
);
34+
35+
await waitFor(() =>
36+
expect(router.state.location.pathname).toEqual(
37+
`/templates/${M.MockDefaultOrganization.name}/${M.MockTemplate.name}`,
38+
),
39+
);
40+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { FC } from "react";
2+
import { Navigate, Outlet, useLocation, useParams } from "react-router-dom";
3+
import type { Organization } from "api/typesGenerated";
4+
import { useDashboard } from "modules/dashboard/useDashboard";
5+
6+
export const TemplateRedirectController: FC = () => {
7+
const { organizations, showOrganizations } = useDashboard();
8+
const { organization, template } = useParams() as {
9+
organization?: string;
10+
template: string;
11+
};
12+
const location = useLocation();
13+
14+
// We redirect templates without an organization to the default organization,
15+
// as that's likely what any links floating around expect.
16+
if (showOrganizations && !organization) {
17+
const extraPath = removePrefix(location.pathname, `/templates/${template}`);
18+
19+
return (
20+
<Navigate
21+
to={`/templates/${getOrganizationNameByDefault(
22+
organizations,
23+
)}/${template}${extraPath}${location.search}`}
24+
replace
25+
/>
26+
);
27+
}
28+
29+
// `showOrganizations` can only be false when there is a single organization,
30+
// so it's safe to throw away the organization name.
31+
if (!showOrganizations && organization) {
32+
const extraPath = removePrefix(
33+
location.pathname,
34+
`/templates/${organization}/${template}`,
35+
);
36+
37+
return (
38+
<Navigate
39+
to={`/templates/${template}${extraPath}${location.search}`}
40+
replace
41+
/>
42+
);
43+
}
44+
45+
return <Outlet />;
46+
};
47+
48+
const getOrganizationNameByDefault = (organizations: Organization[]) =>
49+
organizations.find((org) => org.is_default)?.name;
50+
51+
// I really hate doing it this way, but React Router does not provide a better way.
52+
const removePrefix = (self: string, prefix: string) =>
53+
self.startsWith(prefix) ? self.slice(prefix.length) : self;

site/src/router.tsx

+22-19
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { Suspense, lazy } from "react";
1+
import { lazy, Suspense } from "react";
22
import {
33
createBrowserRouter,
44
createRoutesFromChildren,
55
Navigate,
66
Outlet,
77
Route,
88
} from "react-router-dom";
9+
import { TemplateRedirectController } from "pages/TemplatePage/TemplateRedirectController";
910
import { Loader } from "./components/Loader/Loader";
1011
import { RequireAuth } from "./contexts/auth/RequireAuth";
1112
import { DashboardLayout } from "./modules/dashboard/DashboardLayout";
@@ -289,27 +290,29 @@ const RoutesWithSuspense = () => {
289290
const templateRouter = () => {
290291
return (
291292
<Route path=":template">
292-
<Route element={<TemplateLayout />}>
293-
<Route index element={<TemplateSummaryPage />} />
294-
<Route path="docs" element={<TemplateDocsPage />} />
295-
<Route path="files" element={<TemplateFilesPage />} />
296-
<Route path="versions" element={<TemplateVersionsPage />} />
297-
<Route path="embed" element={<TemplateEmbedPage />} />
298-
<Route path="insights" element={<TemplateInsightsPage />} />
299-
</Route>
293+
<Route element={<TemplateRedirectController />}>
294+
<Route element={<TemplateLayout />}>
295+
<Route index element={<TemplateSummaryPage />} />
296+
<Route path="docs" element={<TemplateDocsPage />} />
297+
<Route path="files" element={<TemplateFilesPage />} />
298+
<Route path="versions" element={<TemplateVersionsPage />} />
299+
<Route path="embed" element={<TemplateEmbedPage />} />
300+
<Route path="insights" element={<TemplateInsightsPage />} />
301+
</Route>
300302

301-
<Route path="workspace" element={<CreateWorkspacePage />} />
303+
<Route path="workspace" element={<CreateWorkspacePage />} />
302304

303-
<Route path="settings" element={<TemplateSettingsLayout />}>
304-
<Route index element={<TemplateSettingsPage />} />
305-
<Route path="permissions" element={<TemplatePermissionsPage />} />
306-
<Route path="variables" element={<TemplateVariablesPage />} />
307-
<Route path="schedule" element={<TemplateSchedulePage />} />
308-
</Route>
305+
<Route path="settings" element={<TemplateSettingsLayout />}>
306+
<Route index element={<TemplateSettingsPage />} />
307+
<Route path="permissions" element={<TemplatePermissionsPage />} />
308+
<Route path="variables" element={<TemplateVariablesPage />} />
309+
<Route path="schedule" element={<TemplateSchedulePage />} />
310+
</Route>
309311

310-
<Route path="versions">
311-
<Route path=":version">
312-
<Route index element={<TemplateVersionPage />} />
312+
<Route path="versions">
313+
<Route path=":version">
314+
<Route index element={<TemplateVersionPage />} />
315+
</Route>
313316
</Route>
314317
</Route>
315318
</Route>

0 commit comments

Comments
 (0)