mod-arch-shared
Version:
Shared UI components and utilities for modular architecture micro-frontend projects
61 lines • 2.7 kB
JavaScript
import * as React from 'react';
import { useBlocker } from 'react-router-dom';
import { Button } from '@patternfly/react-core';
import { Modal, ModalVariant } from '@patternfly/react-core/deprecated';
/**
* A modal that warns users they have unsaved changes when they try to navigate away.
* Uses React Router's useBlocker hook to detect navigation attempts.
*/
const NavigationBlockerModal = ({ hasUnsavedChanges, onDiscardEditsClick, }) => {
const [showModal, setShowModal] = React.useState(false);
const proceedRef = React.useRef();
const resetRef = React.useRef();
const handlingRef = React.useRef(false);
const blocker = useBlocker(React.useCallback(({ currentLocation, nextLocation }) => hasUnsavedChanges &&
currentLocation.pathname !== nextLocation.pathname &&
!handlingRef.current, [hasUnsavedChanges]));
React.useEffect(() => {
if (!hasUnsavedChanges && showModal && proceedRef.current) {
handlingRef.current = true;
proceedRef.current();
setShowModal(false);
}
}, [hasUnsavedChanges, showModal]);
React.useEffect(() => {
switch (blocker.state) {
case 'blocked':
proceedRef.current = blocker.proceed;
resetRef.current = blocker.reset;
setShowModal(true);
break;
case 'proceeding':
handlingRef.current = true;
setShowModal(false);
break;
default:
handlingRef.current = false;
}
}, [blocker]);
const handleConfirm = () => {
handlingRef.current = true;
onDiscardEditsClick?.();
setShowModal(false);
proceedRef.current?.();
};
const handleCancel = () => {
setShowModal(false);
resetRef.current?.();
setTimeout(() => {
handlingRef.current = false;
}, 100);
};
if (!showModal) {
return null;
}
return (React.createElement(Modal, { variant: ModalVariant.small, title: "Discard unsaved changes?", isOpen: true, onClose: handleCancel, actions: [
React.createElement(Button, { key: "confirm", variant: "primary", onClick: handleConfirm, "data-testid": "confirm-discard-changes" }, "Discard"),
React.createElement(Button, { key: "cancel", variant: "link", onClick: handleCancel, "data-testid": "cancel-discard-changes" }, "Cancel"),
] }, "One or more of your changes on this page are not saved yet. Discard your changes and leave this page, or cancel to continue editing."));
};
export default NavigationBlockerModal;
//# sourceMappingURL=NavigationBlockerModal.js.map