91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
|
/**
|
||
|
* External dependencies
|
||
|
*/
|
||
|
import { ComponentType, useEffect, useMemo, useState } from 'react';
|
||
|
import { WP_REST_API_Category } from 'wp-types';
|
||
|
import { ProductResponseItem } from '@woocommerce/types';
|
||
|
import { useDispatch, useSelect } from '@wordpress/data';
|
||
|
|
||
|
/**
|
||
|
* Internal dependencies
|
||
|
*/
|
||
|
import { EditorBlock } from './types';
|
||
|
|
||
|
interface WithUpdateButtonRequiredAttributes {
|
||
|
editMode: boolean;
|
||
|
}
|
||
|
|
||
|
interface WithUpdateButtonAttributes< T > {
|
||
|
attributes: WithUpdateButtonRequiredAttributes &
|
||
|
EditorBlock< T >[ 'attributes' ];
|
||
|
}
|
||
|
|
||
|
interface WithUpdateButtonCategoryProps< T >
|
||
|
extends WithUpdateButtonAttributes< T > {
|
||
|
category: WP_REST_API_Category;
|
||
|
product: never;
|
||
|
}
|
||
|
|
||
|
interface WithUpdateButtonProductProps< T >
|
||
|
extends WithUpdateButtonAttributes< T > {
|
||
|
category: never;
|
||
|
product: ProductResponseItem;
|
||
|
}
|
||
|
|
||
|
type WithUpdateButtonProps< T extends EditorBlock< T > > =
|
||
|
| ( T & WithUpdateButtonCategoryProps< T > )
|
||
|
| ( T & WithUpdateButtonProductProps< T > );
|
||
|
|
||
|
export const withUpdateButtonAttributes = < T extends EditorBlock< T > >(
|
||
|
Component: ComponentType< T >
|
||
|
) => ( props: WithUpdateButtonProps< T > ) => {
|
||
|
const [ doUrlUpdate, setDoUrlUpdate ] = useState( false );
|
||
|
const { attributes, category, clientId, product } = props;
|
||
|
const item = category || product;
|
||
|
|
||
|
const { editMode } = attributes;
|
||
|
const permalink =
|
||
|
( item as WP_REST_API_Category )?.link ||
|
||
|
( item as ProductResponseItem )?.permalink;
|
||
|
|
||
|
const Block = useSelect( ( select ) => {
|
||
|
return select( 'core/block-editor' ).getBlock( clientId );
|
||
|
} );
|
||
|
const InnerButton = Block?.innerBlocks[ 0 ];
|
||
|
const buttonBlockId = InnerButton?.clientId || '';
|
||
|
const currentButtonAttributes = useMemo(
|
||
|
() => InnerButton?.attributes || {},
|
||
|
[ InnerButton ]
|
||
|
);
|
||
|
const { url } = currentButtonAttributes;
|
||
|
|
||
|
const { updateBlockAttributes } = useDispatch( 'core/block-editor' );
|
||
|
|
||
|
useEffect( () => {
|
||
|
if (
|
||
|
doUrlUpdate &&
|
||
|
buttonBlockId &&
|
||
|
! editMode &&
|
||
|
permalink &&
|
||
|
url &&
|
||
|
permalink !== url
|
||
|
) {
|
||
|
updateBlockAttributes( buttonBlockId, {
|
||
|
url: permalink,
|
||
|
} );
|
||
|
setDoUrlUpdate( false );
|
||
|
}
|
||
|
}, [
|
||
|
buttonBlockId,
|
||
|
doUrlUpdate,
|
||
|
editMode,
|
||
|
permalink,
|
||
|
updateBlockAttributes,
|
||
|
url,
|
||
|
] );
|
||
|
|
||
|
const triggerUrlUpdate = () => setDoUrlUpdate( true );
|
||
|
|
||
|
return <Component { ...props } triggerUrlUpdate={ triggerUrlUpdate } />;
|
||
|
};
|