Move usePreventLeavingPage to navigation package (#36752)
* Move usePreventLeavingPage to navigation package * Rename usePreventLeavingPage to useConfirmUnsavedChanges * Move imports to external dependencies * Fix up history push overrides * Add changelog entries * Fix up rebase issues * Update i18n dependency to wp-6.0 * Fix up lock file * Remove unused imports * Update lock file * Remove self import for navUtils
This commit is contained in:
parent
1c9b3a58fe
commit
77937dd8cb
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add hook to check unsaved form changes before page navigation
|
|
@ -31,6 +31,7 @@
|
|||
"@wordpress/compose": "wp-6.0",
|
||||
"@wordpress/element": "wp-6.0",
|
||||
"@wordpress/hooks": "wp-6.0",
|
||||
"@wordpress/i18n": "wp-6.0",
|
||||
"@wordpress/notices": "wp-6.0",
|
||||
"@wordpress/url": "wp-6.0",
|
||||
"history": "^5.3.0",
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useContext, useEffect, useMemo } from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { parseAdminUrl } from '@woocommerce/navigation';
|
||||
import {
|
||||
Location,
|
||||
UNSAFE_NavigationContext as NavigationContext,
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
import { Location } from 'react-router-dom';
|
||||
import { useEffect, useMemo } from '@wordpress/element';
|
||||
|
||||
export default function usePreventLeavingPage(
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getHistory } from '../history';
|
||||
import { parseAdminUrl } from '../';
|
||||
|
||||
export const useConfirmUnsavedChanges = (
|
||||
hasUnsavedChanges: boolean,
|
||||
shouldConfirm?: ( path: URL, fromUrl: Location ) => boolean,
|
||||
/**
|
||||
|
@ -19,24 +20,24 @@ export default function usePreventLeavingPage(
|
|||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#compatibility_notes
|
||||
*/
|
||||
message?: string
|
||||
) {
|
||||
) => {
|
||||
const confirmMessage = useMemo(
|
||||
() =>
|
||||
message ??
|
||||
__( 'Changes you made may not be saved.', 'woocommerce' ),
|
||||
[ message ]
|
||||
);
|
||||
const { navigator } = useContext( NavigationContext );
|
||||
const fromUrl = useLocation();
|
||||
const history = getHistory();
|
||||
|
||||
// This effect prevent react router from navigate and show
|
||||
// a confirmation message. It's a work around to beforeunload
|
||||
// because react router does not triggers that event.
|
||||
useEffect( () => {
|
||||
if ( hasUnsavedChanges ) {
|
||||
const push = navigator.push;
|
||||
const push = history.push;
|
||||
|
||||
navigator.push = ( ...args: Parameters< typeof push > ) => {
|
||||
history.push = ( ...args: Parameters< typeof push > ) => {
|
||||
const fromUrl = history.location;
|
||||
const toUrl = parseAdminUrl( args[ 0 ] ) as URL;
|
||||
if (
|
||||
typeof shouldConfirm === 'function' &&
|
||||
|
@ -54,10 +55,10 @@ export default function usePreventLeavingPage(
|
|||
};
|
||||
|
||||
return () => {
|
||||
navigator.push = push;
|
||||
history.push = push;
|
||||
};
|
||||
}
|
||||
}, [ navigator, hasUnsavedChanges, confirmMessage ] );
|
||||
}, [ history, hasUnsavedChanges, confirmMessage ] );
|
||||
|
||||
// This effect listen to the native beforeunload event to show
|
||||
// a confirmation message
|
||||
|
@ -79,4 +80,4 @@ export default function usePreventLeavingPage(
|
|||
};
|
||||
}
|
||||
}, [ hasUnsavedChanges, confirmMessage ] );
|
||||
}
|
||||
};
|
|
@ -18,9 +18,6 @@ import { getAdminLink } from '@woocommerce/settings';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { getHistory } from './history';
|
||||
import * as navUtils from './index';
|
||||
|
||||
// For the above, import the module into itself. Functions consumed from this import can be mocked in tests.
|
||||
|
||||
// Expose history so all uses get the same history object.
|
||||
export { getHistory };
|
||||
|
@ -28,6 +25,9 @@ export { getHistory };
|
|||
// Export all filter utilities
|
||||
export * from './filters';
|
||||
|
||||
// Export all hooks
|
||||
export { useConfirmUnsavedChanges } from './hooks/use-confirm-unsaved-changes';
|
||||
|
||||
const TIME_EXCLUDED_SCREENS_FILTER = 'woocommerce_admin_time_excluded_screens';
|
||||
|
||||
/**
|
||||
|
@ -79,7 +79,7 @@ export function getNewPath(
|
|||
* @param {Object} query Query containing the parameters.
|
||||
* @return {Object} Object containing the persisted queries.
|
||||
*/
|
||||
export const getPersistedQuery = ( query = navUtils.getQuery() ) => {
|
||||
export const getPersistedQuery = ( query = getQuery() ) => {
|
||||
/**
|
||||
* Filter persisted queries. These query parameters remain in the url when other parameters are updated.
|
||||
*
|
||||
|
@ -226,7 +226,7 @@ export function getIdsFromQuery( queryString = '' ) {
|
|||
* @param {Object} query Query object.
|
||||
* @return {Array} List of search words.
|
||||
*/
|
||||
export function getSearchWords( query = navUtils.getQuery() ) {
|
||||
export function getSearchWords( query = getQuery() ) {
|
||||
if ( typeof query !== 'object' ) {
|
||||
throw new Error(
|
||||
'Invalid parameter passed to getSearchWords, it expects an object or no parameters.'
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from '@woocommerce/product-editor';
|
||||
import { Product } from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
import { navigateTo } from '@woocommerce/navigation';
|
||||
import { navigateTo, useConfirmUnsavedChanges } from '@woocommerce/navigation';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore No types for this exist yet.
|
||||
|
@ -30,7 +30,6 @@ import { store } from '@wordpress/viewport';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import usePreventLeavingPage from '~/hooks/usePreventLeavingPage';
|
||||
import './product-form-actions.scss';
|
||||
import { useProductMVPCESFooter } from '~/customer-effort-score-tracks/use-product-mvp-ces-footer';
|
||||
|
||||
|
@ -50,7 +49,7 @@ export const ProductFormActions: React.FC = () => {
|
|||
const { isDirty, isValidForm, values, resetForm } =
|
||||
useFormContext< Product >();
|
||||
|
||||
usePreventLeavingPage( isDirty, preventLeavingProductForm );
|
||||
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm );
|
||||
|
||||
useCustomerEffortScoreExitPageTracker(
|
||||
! values.id ? 'new_product' : 'editing_new_product',
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
import { preventLeavingProductForm } from '@woocommerce/product-editor';
|
||||
import { registerPlugin } from '@wordpress/plugins';
|
||||
import { useDispatch } from '@wordpress/data';
|
||||
import { useConfirmUnsavedChanges } from '@woocommerce/navigation';
|
||||
import { useFormContext } from '@woocommerce/components';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useState } from '@wordpress/element';
|
||||
|
@ -18,7 +19,6 @@ import { useState } from '@wordpress/element';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import usePreventLeavingPage from '~/hooks/usePreventLeavingPage';
|
||||
import './product-form-actions.scss';
|
||||
|
||||
export const ProductVariationFormActions: React.FC = () => {
|
||||
|
@ -31,7 +31,7 @@ export const ProductVariationFormActions: React.FC = () => {
|
|||
const { createNotice } = useDispatch( 'core/notices' );
|
||||
const [ isSaving, setIsSaving ] = useState( false );
|
||||
|
||||
usePreventLeavingPage( isDirty, preventLeavingProductForm );
|
||||
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm );
|
||||
|
||||
const onSave = async () => {
|
||||
setIsSaving( true );
|
||||
|
|
|
@ -53,7 +53,10 @@ jest.mock( '@woocommerce/product-editor', () => {
|
|||
} ),
|
||||
};
|
||||
} );
|
||||
jest.mock( '~/hooks/usePreventLeavingPage' );
|
||||
jest.mock( '@woocommerce/navigation', () => ( {
|
||||
...jest.requireActual( '@woocommerce/navigation' ),
|
||||
useConfirmUnsavedChanges: jest.fn(),
|
||||
} ) );
|
||||
jest.mock( '@woocommerce/customer-effort-score', () => ( {
|
||||
useCustomerEffortScoreExitPageTracker: jest.fn(),
|
||||
} ) );
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: dev
|
||||
|
||||
Move hook to confirm unsaved form changes to navigation package
|
2388
pnpm-lock.yaml
2388
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue