Files
pp-tcms/frontend/utils/formGuard.ts

55 lines
1.5 KiB
TypeScript

import { useEffect } from 'react';
const isIgnoredPath = (href: string, compiledPatterns: RegExp[]): boolean => {
return compiledPatterns.some((regex) => regex.test(href));
};
export const useFormGuard = (isDirty: boolean, confirmText: string, ignorePathPatterns?: string[]) => {
useEffect(() => {
const compiledPatterns: RegExp[] = (ignorePathPatterns ?? []).flatMap((pattern) => {
try {
return [new RegExp(pattern)];
} catch {
return [];
}
});
const handleClick = (event: MouseEvent) => {
if (!isDirty) return;
if (event.target instanceof Element) {
const anchor = event.target.closest('a:not([target="_blank"])');
if (!anchor) return;
const href = anchor.getAttribute('href');
if (!href) return;
// do not show confirm for ignored paths
if (isIgnoredPath(href, compiledPatterns)) {
return;
}
if (!window.confirm(confirmText)) {
event.preventDefault();
event.stopPropagation();
}
}
};
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (isDirty) {
event.preventDefault();
return (event.returnValue = '');
}
};
window.addEventListener('beforeunload', handleBeforeUnload);
window.addEventListener('click', handleClick, true);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
window.removeEventListener('click', handleClick, true);
};
}, [confirmText, isDirty, ignorePathPatterns]);
};