const { __ } = wp.i18n; const { Toolbar, withAPIData, Dropdown } = wp.components; const { TransitionGroup, CSSTransition } = ReactTransitionGroup; /** * When the display mode is 'Specific products' search for and add products to the block. * * @todo Add the functionality and everything. */ export class ProductsSpecificSelect extends React.Component { /** * Constructor. */ constructor( props ) { super( props ); this.state = { selectedProducts: props.selected_display_setting || [], } } /** * Add a product to the list of selected products. * * @param id int Product ID. */ addProduct( id ) { let selectedProducts = this.state.selectedProducts; selectedProducts.push( id ); this.setState( { selectedProducts: selectedProducts } ); this.props.update_display_setting_callback( selectedProducts ); } /** * Remove a product from the list of selected products. * * @param id int Product ID. */ removeProduct( id ) { let oldProducts = this.state.selectedProducts; let newProducts = []; for ( let productId of oldProducts ) { if ( productId !== id ) { newProducts.push( productId ); } } this.setState( { selectedProducts: newProducts } ); this.props.update_display_setting_callback( newProducts ); } /** * Render the product specific select screen. */ render() { return (
); } } /** * Product search area */ class ProductsSpecificSearchField extends React.Component { /** * Constructor. */ constructor( props ) { super( props ); this.state = { searchText: '', } this.updateSearchResults = this.updateSearchResults.bind( this ); } /** * Event handler for updating results when text is typed into the input. * * @param evt Event object. */ updateSearchResults( evt ) { this.setState( { searchText: evt.target.value, } ); } /** * Render the product search UI. */ render() { return (
{ this.setState( { searchText: '' } ); } } >X
); } } /** * Render product search results based on the text entered into the textbox. */ const ProductSpecificSearchResults = withAPIData( ( props ) => { if ( ! props.searchString.length ) { return { products: [] }; } return { products: '/wc/v2/products?per_page=10&search=' + props.searchString, }; } )( ( { products, addProductCallback, selectedProducts } ) => { if ( ! products.data ) { return null; } if ( 0 === products.data.length ) { return __( 'No products found' ); } return } ); /** * The dropdown of search results. */ class ProductSpecificSearchResultsDropdown extends React.Component { /** * Render dropdown. */ render() { const { products, addProductCallback, selectedProducts } = this.props; let productElements = []; for ( let product of products ) { if ( selectedProducts.includes( product.id ) ) { continue; } productElements.push( ); } return (
); } } /** * One search result. */ class ProductSpecificSearchResultsDropdownElement extends React.Component { /** * Constructor. */ constructor( props ) { super( props ); this.state = { clicked: false, } this.handleClick = this.handleClick.bind( this ); } /** * Add product to main list and change UI to show it was added. */ handleClick() { this.setState( { clicked: true } ); this.props.addProductCallback( this.props.product.id ); } /** * Render one result in the search results. */ render() { const product = this.props.product; return (
  • ); } } /** * List preview of selected products. */ const ProductSpecificSelectedProducts = withAPIData( ( props ) => { if ( ! props.products.length ) { return { products: [] }; } return { products: '/wc/v2/products?include=' + props.products.join( ',' ) }; } )( ( { products, removeProductCallback } ) => { if ( ! products.data ) { return null; } if ( 0 === products.data.length ) { return __( 'No products selected' ); } return (
    ); } );