[useUnsavedChangesPrompt] Don't prompt when history is replaced given its option. (#225471)

## 📓 Summary

Fixes an issue with prompting the user about leaving the page when the
URL changes due to data source changes.



https://github.com/user-attachments/assets/88e36769-96a4-4499-87f0-1e6db4502725
This commit is contained in:
Marco Antonio Ghiani 2025-06-26 18:28:26 +02:00 committed by GitHub
parent 749aeb70e9
commit 2de5294819
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 3 deletions

View file

@ -119,4 +119,24 @@ describe('useUnsavedChangesPrompt', () => {
expect(blockSpy).not.toBeCalled();
});
it('should not block if replaced when shouldPromptOnReplace is false', () => {
renderHook(() =>
useUnsavedChangesPrompt({
hasUnsavedChanges: false,
http: coreStart.http,
openConfirm: coreStart.overlays.openConfirm,
history,
navigateToUrl,
shouldPromptOnReplace: false,
})
);
act(() => history.replace('/test'));
expect(history.location.pathname).toBe('/test');
expect(history.location.search).toBe('');
expect(coreStart.overlays.openConfirm).not.toBeCalled();
expect(addSpy).not.toBeCalledWith('beforeunload', expect.anything());
});
});

View file

@ -42,10 +42,12 @@ interface SpaBlockingProps extends BaseProps {
cancelButtonText?: string;
confirmButtonText?: string;
blockSpaNavigation?: true;
shouldPromptOnReplace?: boolean;
}
interface BrowserBlockingProps extends BaseProps {
blockSpaNavigation: false;
shouldPromptOnReplace?: boolean;
}
type Props = SpaBlockingProps | BrowserBlockingProps;
@ -54,7 +56,7 @@ const isSpaBlocking = (props: Props): props is SpaBlockingProps =>
props.blockSpaNavigation !== false;
export const useUnsavedChangesPrompt = (props: Props) => {
const { hasUnsavedChanges, blockSpaNavigation = true } = props;
const { hasUnsavedChanges, blockSpaNavigation = true, shouldPromptOnReplace = true } = props;
useEffect(() => {
if (hasUnsavedChanges) {
@ -87,7 +89,11 @@ export const useUnsavedChangesPrompt = (props: Props) => {
cancelButtonText = DEFAULT_CANCEL_BUTTON,
} = props;
const unblock = history.block((state) => {
const unblock = history.block((state, action) => {
if (!shouldPromptOnReplace && action === 'REPLACE') {
return;
}
async function confirmAsync() {
const confirmResponse = await openConfirm(messageText, {
title: titleText,
@ -113,5 +119,5 @@ export const useUnsavedChangesPrompt = (props: Props) => {
});
return unblock;
}, [hasUnsavedChanges, blockSpaNavigation, props]);
}, [hasUnsavedChanges, blockSpaNavigation, shouldPromptOnReplace, props]);
};

View file

@ -89,6 +89,7 @@ export function StreamDetailEnrichmentContentImpl() {
http: core.http,
navigateToUrl: core.application.navigateToUrl,
openConfirm: core.overlays.openConfirm,
shouldPromptOnReplace: false,
});
if (!isReady) {