2019-09-04 16:07:00 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2020-04-24 13:36:47 +00:00
|
|
|
import { useState, useEffect } from '@wordpress/element';
|
2019-11-08 16:30:11 +00:00
|
|
|
import { getAttributes, getTerms } from '@woocommerce/block-components/utils';
|
2020-04-24 13:36:47 +00:00
|
|
|
import { find } from 'lodash';
|
2019-09-04 16:07:00 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import { formatError } from '../base/utils/errors.js';
|
|
|
|
|
2019-12-10 17:17:46 +00:00
|
|
|
/**
|
2020-04-24 13:36:47 +00:00
|
|
|
* Get attribute data (name, taxonomy etc) from server data.
|
2019-12-10 17:17:46 +00:00
|
|
|
*
|
2020-04-24 13:36:47 +00:00
|
|
|
* @param {number} attributeId Attribute ID to look for.
|
|
|
|
* @param {Array} attributeList List of attributes.
|
|
|
|
* @param {string} matchField Field to match on. e.g. id or slug.
|
2019-12-10 17:17:46 +00:00
|
|
|
*/
|
2020-04-24 13:36:47 +00:00
|
|
|
const getAttributeData = ( attributeId, attributeList, matchField = 'id' ) => {
|
|
|
|
return attributeList
|
|
|
|
? find( attributeList, [ matchField, attributeId ] )
|
|
|
|
: null;
|
|
|
|
};
|
2019-09-05 15:09:31 +00:00
|
|
|
|
2020-04-24 13:36:47 +00:00
|
|
|
/**
|
|
|
|
* HOC that calls the useAttributes hook.
|
|
|
|
*
|
|
|
|
* @param {Function} OriginalComponent Component being wrapped.
|
|
|
|
*/
|
|
|
|
const withAttributes = ( OriginalComponent ) => {
|
|
|
|
return ( props ) => {
|
|
|
|
const { selected } = props;
|
|
|
|
const [ attributes, setAttributes ] = useState( [] );
|
|
|
|
const [ expandedAttribute, setExpandedAttribute ] = useState( 0 );
|
|
|
|
const [ termsList, setTermsList ] = useState( {} );
|
|
|
|
const [ loading, setLoading ] = useState( true );
|
|
|
|
const [ termsLoading, setTermsLoading ] = useState( false );
|
|
|
|
const [ error, setError ] = useState( null );
|
|
|
|
|
|
|
|
useEffect( () => {
|
2019-09-05 15:09:31 +00:00
|
|
|
getAttributes()
|
2020-04-24 13:36:47 +00:00
|
|
|
.then( ( newAttributes ) => {
|
|
|
|
newAttributes = newAttributes.map( ( attribute ) => ( {
|
|
|
|
...attribute,
|
2019-09-05 15:09:31 +00:00
|
|
|
parent: 0,
|
|
|
|
} ) );
|
2020-04-24 13:36:47 +00:00
|
|
|
|
|
|
|
setAttributes( newAttributes );
|
|
|
|
|
|
|
|
if ( selected.length > 0 ) {
|
|
|
|
const selectedAttributeFromTerm = attributes
|
|
|
|
? getAttributeData(
|
|
|
|
selected[ 0 ].attr_slug,
|
|
|
|
newAttributes,
|
|
|
|
'slug'
|
|
|
|
)
|
|
|
|
: null;
|
|
|
|
|
|
|
|
if ( selectedAttributeFromTerm ) {
|
|
|
|
setExpandedAttribute(
|
|
|
|
selectedAttributeFromTerm.id
|
|
|
|
);
|
2019-09-04 16:07:00 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-05 15:09:31 +00:00
|
|
|
} )
|
|
|
|
.catch( async ( e ) => {
|
2020-04-24 13:36:47 +00:00
|
|
|
setError( await formatError( e ) );
|
|
|
|
} )
|
|
|
|
.finally( () => {
|
|
|
|
setLoading( false );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
2020-04-24 13:36:47 +00:00
|
|
|
}, [] );
|
|
|
|
|
|
|
|
useEffect( () => {
|
|
|
|
const attributeData = attributes
|
|
|
|
? getAttributeData( expandedAttribute, attributes )
|
|
|
|
: null;
|
2019-09-04 16:07:00 +00:00
|
|
|
|
2020-04-24 13:36:47 +00:00
|
|
|
if ( ! attributeData ) {
|
2019-09-05 15:09:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-04-24 13:36:47 +00:00
|
|
|
|
|
|
|
setTermsLoading( true );
|
2019-09-04 16:07:00 +00:00
|
|
|
|
2019-09-05 15:09:31 +00:00
|
|
|
getTerms( expandedAttribute )
|
2020-04-24 13:36:47 +00:00
|
|
|
.then( ( newTerms ) => {
|
|
|
|
newTerms = newTerms.map( ( term ) => ( {
|
2019-09-05 15:09:31 +00:00
|
|
|
...term,
|
|
|
|
parent: expandedAttribute,
|
2020-06-19 14:51:09 +00:00
|
|
|
attr_slug: attributeData.taxonomy,
|
2019-09-05 15:09:31 +00:00
|
|
|
} ) );
|
2019-09-04 16:07:00 +00:00
|
|
|
|
2020-04-24 13:36:47 +00:00
|
|
|
setTermsList( {
|
|
|
|
...termsList,
|
|
|
|
[ expandedAttribute ]: newTerms,
|
2019-09-05 15:09:31 +00:00
|
|
|
} );
|
2020-04-24 13:36:47 +00:00
|
|
|
} )
|
|
|
|
.catch( async ( e ) => {
|
|
|
|
setError( await formatError( e ) );
|
|
|
|
} )
|
|
|
|
.finally( () => {
|
|
|
|
setTermsLoading( false );
|
2019-09-04 16:07:00 +00:00
|
|
|
} );
|
2020-04-24 13:36:47 +00:00
|
|
|
}, [ expandedAttribute, attributes ] );
|
|
|
|
|
|
|
|
return (
|
|
|
|
<OriginalComponent
|
|
|
|
{ ...props }
|
|
|
|
attributes={ attributes }
|
|
|
|
error={ error }
|
|
|
|
expandedAttribute={ expandedAttribute }
|
|
|
|
onExpandAttribute={ setExpandedAttribute }
|
|
|
|
isLoading={ loading }
|
|
|
|
termsAreLoading={ termsLoading }
|
|
|
|
termsList={ termsList }
|
|
|
|
/>
|
|
|
|
);
|
2019-09-05 15:09:31 +00:00
|
|
|
};
|
2020-04-24 13:36:47 +00:00
|
|
|
};
|
2019-09-04 16:07:00 +00:00
|
|
|
|
|
|
|
export default withAttributes;
|