Merge pull request #2914 from ekcom/fix/warn-on-edit-nav

fix: Warn on external navigation during editing
This commit is contained in:
boc-the-git 2024-02-21 21:02:23 +11:00 committed by GitHub
commit 8b88f6892c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 2 deletions

View File

@ -112,6 +112,7 @@ import { useUserApi } from "~/composables/api";
import { uuid4, deepCopy } from "~/composables/use-utils"; import { uuid4, deepCopy } from "~/composables/use-utils";
import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue"; import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue";
import RecipeNotes from "~/components/Domain/Recipe/RecipeNotes.vue"; import RecipeNotes from "~/components/Domain/Recipe/RecipeNotes.vue";
import { useNavigationWarning } from "~/composables/use-navigation-warning";
const EDITOR_OPTIONS = { const EDITOR_OPTIONS = {
mode: "code", mode: "code",
@ -151,6 +152,7 @@ export default defineComponent({
const api = useUserApi(); const api = useUserApi();
const { pageMode, editMode, setMode, isEditForm, isEditJSON, isCookMode, isEditMode, toggleCookMode } = const { pageMode, editMode, setMode, isEditForm, isEditJSON, isCookMode, isEditMode, toggleCookMode } =
usePageState(props.recipe.slug); usePageState(props.recipe.slug);
const { deactivateNavigationWarning } = useNavigationWarning();
/** ============================================================= /** =============================================================
* Recipe Snapshot on Mount * Recipe Snapshot on Mount
@ -175,6 +177,7 @@ export default defineComponent({
await api.recipes.updateOne(props.recipe.slug, props.recipe); await api.recipes.updateOne(props.recipe.slug, props.recipe);
} }
} }
deactivateNavigationWarning();
}); });
/** ============================================================= /** =============================================================

View File

@ -1,5 +1,6 @@
import { computed, ComputedRef, ref, Ref, useContext } from "@nuxtjs/composition-api"; import { computed, ComputedRef, ref, Ref, useContext } from "@nuxtjs/composition-api";
import { UserOut } from "~/lib/api/types/user"; import { UserOut } from "~/lib/api/types/user";
import { useNavigationWarning } from "~/composables/use-navigation-warning";
export enum PageMode { export enum PageMode {
EDIT = "EDIT", EDIT = "EDIT",
@ -65,6 +66,8 @@ function pageRefs(slug: string) {
} }
function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): PageState { function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): PageState {
const { activateNavigationWarning, deactivateNavigationWarning } = useNavigationWarning();
const toggleEditMode = () => { const toggleEditMode = () => {
if (editModeRef.value === EditorMode.FORM) { if (editModeRef.value === EditorMode.FORM) {
editModeRef.value = EditorMode.JSON; editModeRef.value = EditorMode.JSON;
@ -88,8 +91,13 @@ function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): P
const setMode = (toMode: PageMode) => { const setMode = (toMode: PageMode) => {
const fromMode = pageModeRef.value; const fromMode = pageModeRef.value;
if (fromMode === PageMode.EDIT && toMode === PageMode.VIEW) { if (fromMode === PageMode.EDIT) {
setEditMode(EditorMode.FORM); if (toMode === PageMode.VIEW) {
setEditMode(EditorMode.FORM);
}
deactivateNavigationWarning();
} else if (toMode === PageMode.EDIT) {
activateNavigationWarning();
} }
pageModeRef.value = toMode; pageModeRef.value = toMode;

View File

@ -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;
}