diff --git a/frontend/components/Domain/Recipe/RecipePage/RecipePage.vue b/frontend/components/Domain/Recipe/RecipePage/RecipePage.vue index 13ced2946022..91d521723dbc 100644 --- a/frontend/components/Domain/Recipe/RecipePage/RecipePage.vue +++ b/frontend/components/Domain/Recipe/RecipePage/RecipePage.vue @@ -112,6 +112,7 @@ import { useUserApi } from "~/composables/api"; import { uuid4, deepCopy } from "~/composables/use-utils"; import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue"; import RecipeNotes from "~/components/Domain/Recipe/RecipeNotes.vue"; +import { useNavigationWarning } from "~/composables/use-navigation-warning"; const EDITOR_OPTIONS = { mode: "code", @@ -151,6 +152,7 @@ export default defineComponent({ const api = useUserApi(); const { pageMode, editMode, setMode, isEditForm, isEditJSON, isCookMode, isEditMode, toggleCookMode } = usePageState(props.recipe.slug); + const { deactivateNavigationWarning } = useNavigationWarning(); /** ============================================================= * Recipe Snapshot on Mount @@ -175,6 +177,7 @@ export default defineComponent({ await api.recipes.updateOne(props.recipe.slug, props.recipe); } } + deactivateNavigationWarning(); }); /** ============================================================= diff --git a/frontend/composables/recipe-page/shared-state.ts b/frontend/composables/recipe-page/shared-state.ts index bbc040dfb368..5e981fcdb891 100644 --- a/frontend/composables/recipe-page/shared-state.ts +++ b/frontend/composables/recipe-page/shared-state.ts @@ -1,5 +1,6 @@ import { computed, ComputedRef, ref, Ref, useContext } from "@nuxtjs/composition-api"; import { UserOut } from "~/lib/api/types/user"; +import { useNavigationWarning } from "~/composables/use-navigation-warning"; export enum PageMode { EDIT = "EDIT", @@ -65,6 +66,8 @@ function pageRefs(slug: string) { } function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): PageState { + const { activateNavigationWarning, deactivateNavigationWarning } = useNavigationWarning(); + const toggleEditMode = () => { if (editModeRef.value === EditorMode.FORM) { editModeRef.value = EditorMode.JSON; @@ -88,8 +91,13 @@ function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): P const setMode = (toMode: PageMode) => { const fromMode = pageModeRef.value; - if (fromMode === PageMode.EDIT && toMode === PageMode.VIEW) { - setEditMode(EditorMode.FORM); + if (fromMode === PageMode.EDIT) { + if (toMode === PageMode.VIEW) { + setEditMode(EditorMode.FORM); + } + deactivateNavigationWarning(); + } else if (toMode === PageMode.EDIT) { + activateNavigationWarning(); } pageModeRef.value = toMode; diff --git a/frontend/composables/use-navigation-warning.ts b/frontend/composables/use-navigation-warning.ts new file mode 100644 index 000000000000..85cf0b85e69b --- /dev/null +++ b/frontend/composables/use-navigation-warning.ts @@ -0,0 +1,20 @@ +export function useNavigationWarning() { + return { activateNavigationWarning, deactivateNavigationWarning }; +} + +/** + * Displays a warning before the user navigates to another page + * e.g., by clicking a link (which isn't internal and rendered without page load), + * reloading the page, + * or closing the tab. + */ +const activateNavigationWarning = () => { + window.onbeforeunload = () => true; +} + +/** + * Disables the warning when navigating to a page + */ +const deactivateNavigationWarning = () => { + window.onbeforeunload = null; +}