ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
61 lines • 2.85 kB
JavaScript
import { useContext, useEffect, useRef } from 'react';
import { useFormState } from 'react-hook-form';
import { UNSAFE_NavigationContext, useLocation } from 'react-router-dom';
import { useTranslate } from '../i18n';
/**
* Display a confirmation dialog if the form has unsaved changes.
* - If the user confirms, the navigation continues and the changes are lost.
* - If the user cancels, the navigation is cancelled and the changes are kept.
*/
export var useWarnWhenUnsavedChanges = function (enable, formRootPathname, control) {
// react-router v6 does not yet provide a way to block navigation
// This is planned for a future release
// See https://github.com/remix-run/react-router/issues/8139
var navigator = useContext(UNSAFE_NavigationContext).navigator;
var location = useLocation();
var translate = useTranslate();
var _a = useFormState(control ? { control: control } : undefined), isSubmitSuccessful = _a.isSubmitSuccessful, isSubmitting = _a.isSubmitting, dirtyFields = _a.dirtyFields;
var isDirty = Object.keys(dirtyFields).length > 0;
var initialLocation = useRef(formRootPathname || location.pathname);
useEffect(function () {
if (!enable || !isDirty)
return;
if (!navigator.block) {
if (process.env.NODE_ENV !== 'production') {
console.warn('warnWhenUnsavedChanged is not compatible with react-router >= 6.4. If you need this feature, please downgrade react-router to 6.3.0');
}
return;
}
var unblock = navigator.block(function (tx) {
var newLocationIsInsideCurrentLocation = tx.location.pathname.startsWith(initialLocation.current);
var newLocationIsShowView = tx.location.pathname.startsWith("".concat(initialLocation.current, "/show"));
var newLocationIsInsideForm = newLocationIsInsideCurrentLocation && !newLocationIsShowView;
if (!isSubmitting &&
(newLocationIsInsideForm ||
isSubmitSuccessful ||
window.confirm(translate('ra.message.unsaved_changes')))) {
unblock();
tx.retry();
}
else {
if (isSubmitting) {
// Retry the transition (possibly several times) until the form is no longer submitting.
// The value of 100ms is arbitrary, it allows to give some time between retries.
setTimeout(function () {
tx.retry();
}, 100);
}
}
});
return unblock;
}, [
enable,
location,
navigator,
isDirty,
isSubmitting,
isSubmitSuccessful,
translate,
]);
};
//# sourceMappingURL=useWarnWhenUnsavedChanges.js.map