Skip to content

Commit 44dba18

Browse files
committed
Make it work for react router dom navigation
1 parent ba8f7ae commit 44dba18

File tree

3 files changed

+202
-189
lines changed

3 files changed

+202
-189
lines changed

site/src/App.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { QueryClient, QueryClientProvider } from "react-query";
22
import { type FC, type ReactNode, useEffect, useState } from "react";
33
import { HelmetProvider } from "react-helmet-async";
4-
import { AppRouter } from "./AppRouter";
4+
import { router } from "./router";
55
import { ThemeProvider } from "./contexts/ThemeProvider";
66
import { AuthProvider } from "./contexts/auth/AuthProvider";
77
import { ErrorBoundary } from "./components/ErrorBoundary/ErrorBoundary";
88
import { GlobalSnackbar } from "./components/GlobalSnackbar/GlobalSnackbar";
99
import "./theme/globalFonts";
1010
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
11+
import { RouterProvider } from "react-router-dom";
1112

1213
const defaultQueryClient = new QueryClient({
1314
defaultOptions: {
@@ -61,7 +62,7 @@ export const App: FC = () => {
6162
return (
6263
<AppProviders>
6364
<ErrorBoundary>
64-
<AppRouter />
65+
<RouterProvider router={router} />
6566
</ErrorBoundary>
6667
</AppProviders>
6768
);

site/src/pages/TemplateVersionEditorPage/TemplateVersionEditor.tsx

+39-17
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import Button from "@mui/material/Button";
22
import IconButton from "@mui/material/IconButton";
33
import Tooltip from "@mui/material/Tooltip";
44
import CreateIcon from "@mui/icons-material/AddOutlined";
5-
import { Link as RouterLink } from "react-router-dom";
5+
import {
6+
Link as RouterLink,
7+
unstable_usePrompt as usePrompt,
8+
} from "react-router-dom";
69
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
710
import { type FC, useCallback, useEffect, useRef, useState } from "react";
811
import AlertTitle from "@mui/material/AlertTitle";
@@ -65,8 +68,8 @@ export interface TemplateVersionEditorProps {
6568
defaultFileTree: FileTree;
6669
buildLogs?: ProvisionerJobLog[];
6770
resources?: WorkspaceResource[];
68-
isBuilding?: boolean;
69-
canPublish?: boolean;
71+
isBuilding: boolean;
72+
canPublish: boolean;
7073
onPreview: (files: FileTree) => Promise<void>;
7174
onPublish: () => void;
7275
onConfirmPublish: (data: PublishVersionData) => void;
@@ -179,20 +182,7 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
179182
}
180183
}, [buildLogs]);
181184

182-
useEffect(() => {
183-
const onBeforeUnload = (e: BeforeUnloadEvent) => {
184-
if (canPublish) {
185-
e.preventDefault();
186-
return "You have unpublished changes. Are you sure you want to leave?";
187-
}
188-
};
189-
190-
window.addEventListener("beforeunload", onBeforeUnload);
191-
192-
return () => {
193-
window.removeEventListener("beforeunload", onBeforeUnload);
194-
};
195-
}, [canPublish]);
185+
useLeaveSiteWarning(canPublish);
196186

197187
const canBuild = !isBuilding && dirty;
198188

@@ -666,6 +656,38 @@ export const TemplateVersionEditor: FC<TemplateVersionEditorProps> = ({
666656
);
667657
};
668658

659+
const useLeaveSiteWarning = (enabled: boolean) => {
660+
const MESSAGE =
661+
"You have unpublished changes. Are you sure you want to leave?";
662+
663+
// This works for regular browser actions like close tab and back button
664+
useEffect(() => {
665+
const onBeforeUnload = (e: BeforeUnloadEvent) => {
666+
if (enabled) {
667+
e.preventDefault();
668+
return MESSAGE;
669+
}
670+
};
671+
672+
window.addEventListener("beforeunload", onBeforeUnload);
673+
674+
return () => {
675+
window.removeEventListener("beforeunload", onBeforeUnload);
676+
};
677+
}, [enabled]);
678+
679+
// This is used for react router navigation that is not triggered by the
680+
// browser
681+
usePrompt({
682+
message: MESSAGE,
683+
when: ({ nextLocation }) => {
684+
// We need to check the path because we change the URL when new template
685+
// version is created during builds
686+
return enabled && !nextLocation.pathname.endsWith("/edit");
687+
},
688+
});
689+
};
690+
669691
const styles = {
670692
tab: (theme) => ({
671693
"&:not(:disabled)": {

0 commit comments

Comments
 (0)