mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 03:20:46 +02:00
Fix/redact bug (#6048)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useRef, useEffect } from "react";
|
||||
import { Modal, Text, Button, Group, Stack } from "@mantine/core";
|
||||
import { useNavigationGuard } from "@app/contexts/NavigationContext";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -6,51 +7,69 @@ import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
||||
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
|
||||
import { Z_INDEX_TOAST } from "@app/styles/zIndex";
|
||||
|
||||
interface NavigationWarningModalProps {
|
||||
onApplyAndContinue?: () => Promise<void>;
|
||||
onExportAndContinue?: () => Promise<void>;
|
||||
/** Called when discarding - allows saving applied changes while discarding pending ones */
|
||||
onDiscardAndContinue?: () => Promise<void>;
|
||||
}
|
||||
|
||||
const NavigationWarningModal = ({ onApplyAndContinue, onExportAndContinue, onDiscardAndContinue }: NavigationWarningModalProps) => {
|
||||
const NavigationWarningModal = () => {
|
||||
const { t } = useTranslation();
|
||||
const { showNavigationWarning, hasUnsavedChanges, pendingNavigation, cancelNavigation, confirmNavigation, setHasUnsavedChanges } =
|
||||
useNavigationGuard();
|
||||
const {
|
||||
showNavigationWarning,
|
||||
hasUnsavedChanges,
|
||||
pendingNavigation,
|
||||
cancelNavigation,
|
||||
setHasUnsavedChanges,
|
||||
navigationWarningHandlersRef,
|
||||
} = useNavigationGuard();
|
||||
|
||||
// Store pendingNavigation in a ref so async handlers always have the latest,
|
||||
// not a stale closure captured before an await.
|
||||
const pendingNavigationRef = useRef(pendingNavigation);
|
||||
useEffect(() => {
|
||||
pendingNavigationRef.current = pendingNavigation;
|
||||
}, [pendingNavigation]);
|
||||
|
||||
const handleKeepWorking = () => {
|
||||
cancelNavigation();
|
||||
};
|
||||
|
||||
const handleDiscardChanges = async () => {
|
||||
// If a discard handler is provided, call it to save any already-applied changes, then discard the unsaved changes
|
||||
if (onDiscardAndContinue) {
|
||||
await onDiscardAndContinue();
|
||||
}
|
||||
const finishAndNavigate = () => {
|
||||
const nav = pendingNavigationRef.current;
|
||||
setHasUnsavedChanges(false);
|
||||
confirmNavigation();
|
||||
cancelNavigation();
|
||||
if (nav) {
|
||||
nav();
|
||||
}
|
||||
};
|
||||
|
||||
const handleDiscardChanges = async () => {
|
||||
const handlers = navigationWarningHandlersRef.current;
|
||||
if (handlers?.onDiscardAndContinue) {
|
||||
await handlers.onDiscardAndContinue();
|
||||
}
|
||||
finishAndNavigate();
|
||||
};
|
||||
|
||||
const handleApplyAndContinue = async () => {
|
||||
if (onApplyAndContinue) {
|
||||
await onApplyAndContinue();
|
||||
const handlers = navigationWarningHandlersRef.current;
|
||||
if (handlers?.onApplyAndContinue) {
|
||||
await handlers.onApplyAndContinue();
|
||||
}
|
||||
setHasUnsavedChanges(false);
|
||||
confirmNavigation();
|
||||
finishAndNavigate();
|
||||
};
|
||||
|
||||
const handleExportAndContinue = async () => {
|
||||
if (onExportAndContinue) {
|
||||
await onExportAndContinue();
|
||||
const handlers = navigationWarningHandlersRef.current;
|
||||
if (handlers?.onExportAndContinue) {
|
||||
await handlers.onExportAndContinue();
|
||||
}
|
||||
setHasUnsavedChanges(false);
|
||||
confirmNavigation();
|
||||
finishAndNavigate();
|
||||
};
|
||||
|
||||
// Read handler availability at render time for button visibility
|
||||
const handlers = navigationWarningHandlersRef.current;
|
||||
const hasApply = !!handlers?.onApplyAndContinue;
|
||||
const hasExport = !!handlers?.onExportAndContinue;
|
||||
|
||||
const BUTTON_WIDTH = "12rem";
|
||||
|
||||
// Only show modal if there are unsaved changes AND there's an actual pending navigation
|
||||
// This prevents the modal from showing due to spurious state updates
|
||||
if (!hasUnsavedChanges || !pendingNavigation) {
|
||||
return null;
|
||||
}
|
||||
@@ -87,12 +106,12 @@ const NavigationWarningModal = ({ onApplyAndContinue, onExportAndContinue, onDis
|
||||
<Button variant="filled" color="var(--mantine-color-red-9)" onClick={handleDiscardChanges} w={BUTTON_WIDTH} leftSection={<DeleteOutlineIcon fontSize="small" />}>
|
||||
{t("discardChanges", "Discard Changes")}
|
||||
</Button>
|
||||
{onApplyAndContinue && (
|
||||
{hasApply && (
|
||||
<Button variant="filled" onClick={handleApplyAndContinue} w={BUTTON_WIDTH} leftSection={<CheckCircleOutlineIcon fontSize="small" />}>
|
||||
{t("applyAndContinue", "Apply & Leave")}
|
||||
</Button>
|
||||
)}
|
||||
{onExportAndContinue && (
|
||||
{hasExport && (
|
||||
<Button variant="filled" onClick={handleExportAndContinue} w={BUTTON_WIDTH} leftSection={<CheckCircleOutlineIcon fontSize="small" />}>
|
||||
{t("exportAndContinue", "Export & Leave")}
|
||||
</Button>
|
||||
@@ -108,12 +127,12 @@ const NavigationWarningModal = ({ onApplyAndContinue, onExportAndContinue, onDis
|
||||
<Button variant="filled" color="var(--mantine-color-red-9)" onClick={handleDiscardChanges} w={BUTTON_WIDTH} leftSection={<DeleteOutlineIcon fontSize="small" />}>
|
||||
{t("discardChanges", "Discard Changes")}
|
||||
</Button>
|
||||
{onApplyAndContinue && (
|
||||
{hasApply && (
|
||||
<Button variant="filled" onClick={handleApplyAndContinue} w={BUTTON_WIDTH} leftSection={<CheckCircleOutlineIcon fontSize="small" />}>
|
||||
{t("applyAndContinue", "Apply & Leave")}
|
||||
</Button>
|
||||
)}
|
||||
{onExportAndContinue && (
|
||||
{hasExport && (
|
||||
<Button variant="filled" onClick={handleExportAndContinue} w={BUTTON_WIDTH} leftSection={<CheckCircleOutlineIcon fontSize="small" />}>
|
||||
{t("exportAndContinue", "Export & Leave")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user