woocommerce/plugins/woocommerce-blocks/assets/js/editor-components/default-notice/index.tsx

159 lines
4.2 KiB
TypeScript

/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { store as editorStore } from '@wordpress/editor';
import triggerFetch from '@wordpress/api-fetch';
import { store as coreStore } from '@wordpress/core-data';
import { Notice, Button } from '@wordpress/components';
import { useSelect, useDispatch } from '@wordpress/data';
import { CHECKOUT_PAGE_ID, CART_PAGE_ID } from '@woocommerce/block-settings';
import { useCallback, useState } from '@wordpress/element';
/**
* Internal dependencies
*/
import './editor.scss';
export function DefaultNotice( { block }: { block: string } ) {
// To avoid having the same logic twice, we're going to handle both pages here.
const ORIGINAL_PAGE_ID =
block === 'checkout' ? CHECKOUT_PAGE_ID : CART_PAGE_ID;
const settingName =
block === 'checkout'
? 'woocommerce_checkout_page_id'
: 'woocommerce_cart_page_id';
const noticeContent =
block === 'checkout'
? __(
'If you would like to use this block as your default checkout, update your page settings',
'woo-gutenberg-products-block'
)
: __(
'If you would like to use this block as your default cart, update your page settings',
'woo-gutenberg-products-block'
);
// Everything below works the same for Cart/Checkout
const { saveEntityRecord } = useDispatch( coreStore );
const { editPost, savePost } = useDispatch( editorStore );
const { slug, isLoadingPage, postPublished, currentPostId } = useSelect(
( select ) => {
const { getEntityRecord, isResolving } = select( coreStore );
const { isCurrentPostPublished, getCurrentPostId } =
select( editorStore );
return {
slug:
getEntityRecord( 'postType', 'page', ORIGINAL_PAGE_ID )
?.slug || block,
isLoadingPage: isResolving( 'getEntityRecord', [
'postType',
'page',
ORIGINAL_PAGE_ID,
] ),
postPublished: isCurrentPostPublished(),
currentPostId: getCurrentPostId(),
};
},
[]
);
const [ settingStatus, setStatus ] = useState( 'pristine' );
const updatePage = useCallback( () => {
setStatus( 'updating' );
Promise.resolve()
.then( () =>
triggerFetch( {
path: `/wc/v3/settings/advanced/${ settingName }`,
method: 'GET',
} )
)
.catch( ( error ) => {
if ( error.code === 'rest_setting_setting_invalid' ) {
setStatus( 'error' );
}
} )
.then( () => {
if ( ! postPublished ) {
editPost( { status: 'publish' } );
return savePost();
}
} )
.then( () =>
// Make this page ID the default cart/checkout.
triggerFetch( {
path: `/wc/v3/settings/advanced/${ settingName }`,
method: 'POST',
data: {
value: currentPostId.toString(),
},
} )
)
// Append `-2` to the original link so we can use it here.
.then( () => {
if ( ORIGINAL_PAGE_ID !== 0 ) {
return saveEntityRecord( 'postType', 'page', {
id: ORIGINAL_PAGE_ID,
slug: `${ slug }-2`,
} );
}
} )
// Use the original link for this page.
.then( () => editPost( { slug } ) )
// Save page.
.then( () => savePost() )
.then( () => setStatus( 'updated' ) );
}, [
postPublished,
editPost,
savePost,
settingName,
currentPostId,
ORIGINAL_PAGE_ID,
saveEntityRecord,
slug,
] );
// Avoid showing the notice on the site editor, if already set, or if dismissed earlier.
if (
( typeof pagenow === 'string' && pagenow === 'site-editor' ) ||
currentPostId === ORIGINAL_PAGE_ID ||
settingStatus === 'dismissed'
) {
return null;
}
return (
<Notice
className="wc-default-page-notice"
status={ settingStatus === 'updated' ? 'success' : 'warning' }
onRemove={ () => setStatus( 'dismissed' ) }
spokenMessage={
settingStatus === 'updated'
? __(
'Page settings updated',
'woo-gutenberg-products-block'
)
: noticeContent
}
>
{ settingStatus === 'updated' ? (
__( 'Page settings updated', 'woo-gutenberg-products-block' )
) : (
<>
<p>{ noticeContent }</p>
<Button
onClick={ updatePage }
variant="secondary"
isBusy={ settingStatus === 'updating' }
disabled={ isLoadingPage }
isSmall={ true }
>
{ __(
'Update your page settings',
'woo-gutenberg-products-block'
) }
</Button>
</>
) }
</Notice>
);
}