[WEB-1610] chore: re-implement reload confirmation hook. (#4880)
* [WEB-1610] chore: re-implement reload confirmation hook. * chore: attach anchor event listner to window instead of body.
This commit is contained in:
parent
e04eb1a63d
commit
718453b332
2 changed files with 48 additions and 41 deletions
|
|
@ -2,14 +2,12 @@
|
||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { NodeViewWrapper } from "@tiptap/react";
|
import { NodeViewWrapper } from "@tiptap/react";
|
||||||
import { cn } from "src/lib/utils";
|
import { cn } from "src/lib/utils";
|
||||||
import { useRouter } from "next/navigation";
|
|
||||||
import { IMentionHighlight } from "src/types/mention-suggestion";
|
import { IMentionHighlight } from "src/types/mention-suggestion";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-anonymous-default-export
|
// eslint-disable-next-line import/no-anonymous-default-export
|
||||||
export const MentionNodeView = (props) => {
|
export const MentionNodeView = (props) => {
|
||||||
// TODO: move it to web app
|
// TODO: move it to web app
|
||||||
const router = useRouter();
|
|
||||||
const [highlightsState, setHighlightsState] = useState<IMentionHighlight[]>();
|
const [highlightsState, setHighlightsState] = useState<IMentionHighlight[]>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -21,25 +19,20 @@ export const MentionNodeView = (props) => {
|
||||||
hightlights();
|
hightlights();
|
||||||
}, [props.extension.options]);
|
}, [props.extension.options]);
|
||||||
|
|
||||||
const handleClick = () => {
|
|
||||||
if (!props.extension.options.readonly) {
|
|
||||||
router.push(props.node.attrs.redirect_uri);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="mention-component inline w-fit">
|
<NodeViewWrapper className="mention-component inline w-fit">
|
||||||
<span
|
<a
|
||||||
|
href={props.node.attrs.redirect_uri}
|
||||||
|
target="_blank"
|
||||||
className={cn("mention rounded bg-custom-primary-100/20 px-1 py-0.5 font-medium text-custom-primary-100", {
|
className={cn("mention rounded bg-custom-primary-100/20 px-1 py-0.5 font-medium text-custom-primary-100", {
|
||||||
"bg-yellow-500/20 text-yellow-500": highlightsState
|
"bg-yellow-500/20 text-yellow-500": highlightsState
|
||||||
? highlightsState.includes(props.node.attrs.entity_identifier)
|
? highlightsState.includes(props.node.attrs.entity_identifier)
|
||||||
: false,
|
: false,
|
||||||
"cursor-pointer": !props.extension.options.readonly,
|
"cursor-pointer": !props.extension.options.readonly,
|
||||||
})}
|
})}
|
||||||
onClick={handleClick}
|
|
||||||
>
|
>
|
||||||
@{props.node.attrs.label}
|
@{props.node.attrs.label}
|
||||||
</span>
|
</a>
|
||||||
</NodeViewWrapper>
|
</NodeViewWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,55 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
//TODO: remove temp flag isActive later and use showAlert as the source of truth
|
//TODO: remove temp flag isActive later and use showAlert as the source of truth
|
||||||
const useReloadConfirmations = (isActive = true) => {
|
const useReloadConfirmations = (isActive = true) => {
|
||||||
const [showAlert, setShowAlert] = useState(false);
|
const [showAlert, setShowAlert] = useState(false);
|
||||||
// const router = useAppRouter();
|
|
||||||
|
|
||||||
// const handleBeforeUnload = useCallback(
|
const handleBeforeUnload = useCallback(
|
||||||
// (event: BeforeUnloadEvent) => {
|
(event: BeforeUnloadEvent) => {
|
||||||
// if (!isActive || !showAlert) return;
|
if (!isActive || !showAlert) return;
|
||||||
// event.preventDefault();
|
event.preventDefault();
|
||||||
// event.returnValue = "";
|
event.returnValue = "";
|
||||||
// },
|
},
|
||||||
// [isActive, showAlert]
|
[isActive, showAlert]
|
||||||
// );
|
);
|
||||||
|
|
||||||
// const handleRouteChangeStart = useCallback(
|
const handleAnchorClick = useCallback(
|
||||||
// (url: string, { shallow }: { shallow: boolean }) => {
|
(event: MouseEvent) => {
|
||||||
// if (!isActive || !showAlert) return;
|
if (!isActive || !showAlert) return;
|
||||||
// const leave = confirm("Are you sure you want to leave? Changes you made may not be saved.");
|
// Skip if event target is not available or defaultPrevented
|
||||||
// if (!leave) {
|
if (!event.target || event.defaultPrevented) return;
|
||||||
// router.events.emit("routeChangeError", new Error("Route change cancelled by user"), url, shallow);
|
// Skip control/command/option/alt+click
|
||||||
// throw "routeChange aborted.";
|
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
||||||
// }
|
// check if the event target is an anchor or a child of an anchor tag
|
||||||
// },
|
const eventTarget = event.target as HTMLElement;
|
||||||
// [isActive, router.events, showAlert]
|
if (!eventTarget.closest("a")) return; // This is intentionally not type safe
|
||||||
// );
|
// check if anchor target is _blank
|
||||||
|
const anchorElement = eventTarget.closest("a") as HTMLAnchorElement;
|
||||||
|
const isAnchorTargetBlank = anchorElement.getAttribute("target") === "_blank";
|
||||||
|
if (isAnchorTargetBlank) return;
|
||||||
|
// show confirm dialog
|
||||||
|
const leave = confirm("Are you sure you want to leave? Changes you made may not be saved.");
|
||||||
|
if (!leave) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[isActive, showAlert]
|
||||||
|
);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// window.addEventListener("beforeunload", handleBeforeUnload);
|
// handle browser refresh
|
||||||
// router.events.on("routeChangeStart", handleRouteChangeStart);
|
window.addEventListener("beforeunload", handleBeforeUnload, true);
|
||||||
|
// handle anchor tag click
|
||||||
|
window.addEventListener("click", handleAnchorClick, true);
|
||||||
|
// TODO: handle back / forward button click
|
||||||
|
|
||||||
// return () => {
|
return () => {
|
||||||
// window.removeEventListener("beforeunload", handleBeforeUnload);
|
// cleanup
|
||||||
// router.events.off("routeChangeStart", handleRouteChangeStart);
|
window.removeEventListener("beforeunload", handleBeforeUnload, true);
|
||||||
// };
|
window.removeEventListener("click", handleAnchorClick, true);
|
||||||
// }, [handleBeforeUnload, handleRouteChangeStart, router.events]);
|
};
|
||||||
|
}, [handleAnchorClick, handleBeforeUnload]);
|
||||||
|
|
||||||
return { setShowAlert };
|
return { setShowAlert };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue