This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 221
Implement Hand-Picked Products block #7925
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
b6c8ee7
Implement Hand-Picked Products block
sunyatasattva 318549b
Merge branch 'trunk' into add/7633-handpicked-products
sunyatasattva e26bf2e
Implement PHP-side rendering of handpicked products
sunyatasattva b9cdf71
Add `ProductSelector` to all inspector controls
sunyatasattva 2787e92
Merge branch 'trunk' into add/7633-handpicked-products
sunyatasattva f4879c8
Add docs to function
sunyatasattva 7df46a5
Remove reference to handpicked product variation
sunyatasattva db5377c
Address Code Review feedback
sunyatasattva a57fde6
Merge branch 'trunk' into add/7633-handpicked-products
sunyatasattva cd53e0c
Merge branch 'trunk' into add/7633-handpicked-products
sunyatasattva File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
assets/js/blocks/product-query/inspector-controls/product-selector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { getProducts } from '@woocommerce/editor-components/utils'; | ||
import { ProductResponseItem } from '@woocommerce/types'; | ||
import { objectOmit } from '@woocommerce/utils'; | ||
import { useState, useEffect } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { | ||
FormTokenField, | ||
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis | ||
__experimentalToolsPanelItem as ToolsPanelItem, | ||
} from '@wordpress/components'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { ProductQueryBlock } from '../types'; | ||
import { setQueryAttribute } from '../utils'; | ||
|
||
function useProductsList() { | ||
const [ productsList, setProductsList ] = useState< ProductResponseItem[] >( | ||
[] | ||
); | ||
|
||
useEffect( () => { | ||
getProducts( { selected: [] } ).then( ( results ) => { | ||
setProductsList( results as ProductResponseItem[] ); | ||
} ); | ||
}, [] ); | ||
Comment on lines
+22
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's needed here but just wanted to share my thoughts. Maybe we can create a custom hook to fetch and manage the productsList state to separate concerns and make the component more modular: const useProductsList = (): ProductResponseItem[] => {
const [productsList, setProductsList] = useState<ProductResponseItem[]>([]);
useEffect(() => {
getProducts({ selected: [] }).then((results) => {
setProductsList(results as ProductResponseItem[]);
});
}, []);
return productsList;
}; And use it in the component like this: const productsList = useProductsList(); |
||
|
||
return productsList; | ||
} | ||
|
||
export const ProductSelector = ( props: ProductQueryBlock ) => { | ||
const { query } = props.attributes; | ||
|
||
const productsList = useProductsList(); | ||
|
||
const onTokenChange = ( values: FormTokenField.Value[] ) => { | ||
const ids = values | ||
.map( | ||
( nameOrId ) => | ||
productsList.find( | ||
( product ) => | ||
product.name === nameOrId || | ||
product.id === Number( nameOrId ) | ||
)?.id | ||
) | ||
.filter( Boolean ) | ||
.map( String ); | ||
|
||
if ( ! ids.length && props.attributes.query.include ) { | ||
const prunedQuery = objectOmit( props.attributes.query, 'include' ); | ||
|
||
setQueryAttribute( | ||
{ | ||
...props, | ||
attributes: { | ||
...props.attributes, | ||
query: prunedQuery, | ||
}, | ||
}, | ||
{} | ||
); | ||
} else { | ||
setQueryAttribute( props, { | ||
include: ids, | ||
} ); | ||
} | ||
}; | ||
|
||
return ( | ||
<ToolsPanelItem | ||
label={ __( | ||
'Hand-picked Products', | ||
'woo-gutenberg-products-block' | ||
) } | ||
hasValue={ () => query.include?.length } | ||
> | ||
<FormTokenField | ||
disabled={ ! productsList.length } | ||
displayTransform={ ( token: string ) => | ||
Number.isNaN( Number( token ) ) | ||
? token | ||
: productsList.find( | ||
( product ) => product.id === Number( token ) | ||
)?.name || '' | ||
} | ||
label={ __( | ||
'Pick some products', | ||
'woo-gutenberg-products-block' | ||
) } | ||
onChange={ onTokenChange } | ||
suggestions={ productsList.map( ( product ) => product.name ) } | ||
validateInput={ ( value: string ) => | ||
productsList.find( ( product ) => product.name === value ) | ||
} | ||
value={ | ||
! productsList.length | ||
? [ __( 'Loading…', 'woo-gutenberg-products-block' ) ] | ||
: query?.include || [] | ||
} | ||
__experimentalExpandOnFocus={ true } | ||
/> | ||
</ToolsPanelItem> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Returns an object without a key. | ||
*/ | ||
export function objectOmit< T, K extends keyof T >( obj: T, key: K ) { | ||
const { [ key ]: omit, ...rest } = obj; | ||
|
||
return rest; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thanks for moving this to utils 🙌🏻