Redirect to product editing page when product was still in auto draft (#40225)

* Redirect to product editing page when product was still in auto draft

* Make sure the prevent page does not show up when creating variations

* Add changelog and fix tests
This commit is contained in:
louwie17 2023-09-19 17:33:15 -03:00 committed by GitHub
parent 8b32e47086
commit f9705a531b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 16 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add redirection to product edit page if variations are added before it being saved.

View File

@ -89,7 +89,9 @@ export const AttributeListItem: React.FC< AttributeListItemProps > = ( {
position="top center"
text={ NOT_VISIBLE_TEXT }
>
<HiddenWithHelpIcon />
<div>
<HiddenWithHelpIcon />
</div>
</Tooltip>
) }
{ typeof onEditClick === 'function' && (

View File

@ -33,5 +33,8 @@ export function useConfirmUnsavedProductChanges() {
[ productId ]
);
useConfirmUnsavedChanges( hasEdits || isSaving, preventLeavingProductForm );
useConfirmUnsavedChanges(
hasEdits || isSaving,
preventLeavingProductForm( productId )
);
}

View File

@ -1,11 +1,13 @@
/**
* External dependencies
*/
import { useDispatch } from '@wordpress/data';
import { resolveSelect, useDispatch } from '@wordpress/data';
import { useEntityProp } from '@wordpress/core-data';
import { useCallback, useState } from '@wordpress/element';
import { getNewPath, getPath, navigateTo } from '@woocommerce/navigation';
import {
EXPERIMENTAL_PRODUCT_VARIATIONS_STORE_NAME,
Product,
ProductDefaultAttribute,
} from '@woocommerce/data';
@ -34,6 +36,13 @@ export function useProductVariationsHelper() {
) => {
setIsGenerating( true );
const lastStatus = (
( await resolveSelect( 'core' ).getEditedEntityRecord(
'postType',
'product',
productId
) ) as Product
).status;
const hasVariableAttribute = attributes.some(
( attr ) => attr.variation
);
@ -64,6 +73,13 @@ export function useProductVariationsHelper() {
} )
.finally( () => {
setIsGenerating( false );
if (
lastStatus === 'auto-draft' &&
getPath().endsWith( 'add-product' )
) {
const url = getNewPath( {}, `/product/${ productId }` );
navigateTo( { url } );
}
} );
},
[]

View File

@ -6,10 +6,19 @@ import { Location } from 'react-router-dom';
/**
* Allow switching between tabs without prompting for unsaved changes.
*/
export const preventLeavingProductForm = ( toUrl: URL, fromUrl: Location ) => {
const toParams = new URLSearchParams( toUrl.search );
const fromParams = new URLSearchParams( fromUrl.search );
toParams.delete( 'tab' );
fromParams.delete( 'tab' );
return toParams.toString() !== fromParams.toString();
};
export const preventLeavingProductForm =
( productId?: number ) => ( toUrl: URL, fromUrl: Location ) => {
const toParams = new URLSearchParams( toUrl.search );
const fromParams = new URLSearchParams( fromUrl.search );
toParams.delete( 'tab' );
fromParams.delete( 'tab' );
// Prevent dialog from happening if moving from add new to edit page of same product.
if (
productId !== undefined &&
fromParams.get( 'path' ) === '/add-product' &&
toParams.get( 'path' ) === '/product/' + productId
) {
return false;
}
return toParams.toString() !== fromParams.toString();
};

View File

@ -16,7 +16,7 @@ describe( 'preventLeavingProductForm', () => {
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/product/123&tab=general',
} as Location;
const shouldPrevent = preventLeavingProductForm( toUrl, fromUrl );
const shouldPrevent = preventLeavingProductForm()( toUrl, fromUrl );
expect( shouldPrevent ).toBe( true );
} );
@ -27,7 +27,7 @@ describe( 'preventLeavingProductForm', () => {
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/product/123&tab=general',
} as Location;
const shouldPrevent = preventLeavingProductForm( toUrl, fromUrl );
const shouldPrevent = preventLeavingProductForm()( toUrl, fromUrl );
expect( shouldPrevent ).toBe( true );
} );
@ -38,7 +38,35 @@ describe( 'preventLeavingProductForm', () => {
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/product/123&tab=shipping',
} as Location;
const shouldPrevent = preventLeavingProductForm( toUrl, fromUrl );
const shouldPrevent = preventLeavingProductForm()( toUrl, fromUrl );
expect( shouldPrevent ).toBe( true );
} );
it( 'should allow leaving when moving from the add-product to the edit page with same product id', () => {
const toUrl = new URL(
'http://mysite.com/admin.php?page=wc-admin&path=/product/123&tab=general'
);
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/add-product',
} as Location;
const shouldPrevent = preventLeavingProductForm( 123 )(
toUrl,
fromUrl
);
expect( shouldPrevent ).toBe( false );
} );
it( 'should not allow leaving when moving from the add-product to the edit page with different product id', () => {
const toUrl = new URL(
'http://mysite.com/admin.php?page=wc-admin&path=/product/123&tab=general'
);
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/add-product',
} as Location;
const shouldPrevent = preventLeavingProductForm( 333 )(
toUrl,
fromUrl
);
expect( shouldPrevent ).toBe( true );
} );
@ -49,7 +77,7 @@ describe( 'preventLeavingProductForm', () => {
const fromUrl = {
search: 'admin.php?page=wc-admin&path=/product/123&tab=shipping&other_param=b',
} as Location;
const shouldPrevent = preventLeavingProductForm( toUrl, fromUrl );
const shouldPrevent = preventLeavingProductForm()( toUrl, fromUrl );
expect( shouldPrevent ).toBe( true );
} );
} );

View File

@ -49,7 +49,7 @@ export const ProductFormActions: React.FC = () => {
const { isDirty, isValidForm, values, resetForm } =
useFormContext< Product >();
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm );
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm() );
useCustomerEffortScoreExitPageTracker(
! values.id ? 'new_product' : 'editing_new_product',

View File

@ -31,7 +31,7 @@ export const ProductVariationFormActions: React.FC = () => {
const { createNotice } = useDispatch( 'core/notices' );
const [ isSaving, setIsSaving ] = useState( false );
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm );
useConfirmUnsavedChanges( isDirty, preventLeavingProductForm() );
const onSave = async () => {
setIsSaving( true );

View File

@ -44,6 +44,7 @@ jest.mock( '@woocommerce/product-editor', () => {
__experimentalUseFeedbackBar: () => ( {
maybeShowFeedbackBar: jest.fn().mockResolvedValue( {} ),
} ),
preventLeavingProductForm: () => () => false,
};
} );
jest.mock( '@woocommerce/navigation', () => ( {

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
Update use of preventLeavingProductForm with new function changes.