( function ( wpI18n, wpBlocks, wpElement, wpEditor, wpComponents ) { const { __ } = wpI18n; const { Component, Fragment } = wpElement; const { registerBlockType } = wpBlocks; const { InspectorControls, BlockControls } = wpEditor; const { RangeControl, PanelBody, CheckboxControl, SelectControl, Spinner, Toolbar, Placeholder, Button } = wpComponents; const { addQueryArgs } = wp.url; let fetchingQueue = null; const advProductsBlockIcon = ( ); class AdvProductsEdit extends Component { constructor() { super( ...arguments ); this.state = { categoriesList: [], productsList: [], loading: true, error: false, }; this.fetchProducts = this.fetchProducts.bind(this); } componentWillMount() { const { attributes, setAttributes } = this.props; const currentBlockConfig = advgbDefaultConfig['advgb-woo-products']; // No override attributes of blocks inserted before if (attributes.changed !== true) { if (typeof currentBlockConfig === 'object' && currentBlockConfig !== null) { Object.keys(currentBlockConfig).map((attribute) => { if (typeof attributes[attribute] === 'boolean') { attributes[attribute] = !!currentBlockConfig[attribute]; } else { attributes[attribute] = currentBlockConfig[attribute]; } }); } // Finally set changed attribute to true, so we don't modify anything again setAttributes( { changed: true } ); } this.fetchProducts(); } componentWillUpdate( nextProps, nextState ) { const { clientId } = this.props; const $ = jQuery; if (this.checkAttrChanged(nextProps.attributes, this.props.attributes)) { $(`#block-${clientId} .advgb-products-wrapper.slick-initialized`).slick('unslick'); $(`#block-${clientId} .advgb-product`) .removeAttr('tabindex') .removeAttr('role') .removeAttr('aria-describedby'); } } componentDidUpdate( prevProps ) { const { categoriesList } = this.state; const { attributes } = this.props; const { category } = attributes; if (category === 'selected' && categoriesList.length === 0) { wp.apiFetch( { path: addQueryArgs('/wc/v2/products/categories', {per_page:-1} ) } ).then( (obj) => { this.setState( { categoriesList: obj } ); } ); } if (this.checkAttrChanged( prevProps.attributes, attributes )) { this.fetchProducts(); } } checkAttrChanged( prevAttrs, curAttrs ) { const { viewType: prevView, category: prevCat, categories: prevCats, status: prevStatus, order: prevOrder, orderBy: prevOrderBy, numberOfProducts: prevLength } = prevAttrs; const { viewType, category, categories, status, order, orderBy, numberOfProducts } = curAttrs; return ( category !== prevCat || categories !== prevCats || status !== prevStatus || order !== prevOrder || orderBy !== prevOrderBy || numberOfProducts !== prevLength || prevView !== viewType ) } fetchProducts() { const self = this; const { viewType, category, categories, status, order, orderBy, numberOfProducts, } = this.props.attributes; const query = addQueryArgs( '/agwc/v1/products', { order: order || undefined, orderby: orderBy || undefined, per_page: numberOfProducts, category: category === 'selected' ? categories.join(',') : undefined, featured: status === 'featured' ? 1 : undefined, on_sale: status === 'on_sale' ? 1 : undefined, } ); if (fetchingQueue) { clearTimeout(fetchingQueue); } if (this.state.error) { this.setState( { error: false } ); } fetchingQueue = setTimeout(function () { if (!self.state.loading) { self.setState( { loading: true } ); } wp.apiFetch( { path: query } ).then( (obj) => { self.setState( { productsList: obj, loading: false, } ) } ).catch( (error) => { self.setState( { loading: false, error: true, } ) } ).then( () => { if (viewType === 'slider') { $(`#block-${self.props.clientId} .advgb-products-block.slider-view .advgb-products-wrapper:not(.slick-initialized)`).slick( { dots: true, adaptiveHeight: true, } ); } } ) }, 500 ); } setCategories( catID, willAdd ) { const { attributes, setAttributes } = this.props; const { categories } = attributes; if (willAdd) { setAttributes( { categories: [ ...categories, catID ] } ); } else { setAttributes( { categories: categories.filter( (cat) => cat !== catID ) } ) } this.fetchProducts(); } render() { const { categoriesList, productsList, loading, error } = this.state; const { attributes, setAttributes } = this.props; const { viewType, category, categories, status, order, orderBy, numberOfProducts, columns, } = attributes; const viewControls = [ { icon: 'grid-view', title: __( 'Normal View' ), onClick: () => setAttributes( { viewType: 'normal' } ), isActive: viewType === 'normal', }, { icon: 'slides', title: __( 'Slider View' ), onClick: () => setAttributes( { viewType: 'slider' } ), isActive: viewType === 'slider', }, ]; const blockClassName = [ "advgb-products-block", viewType === 'slider' && 'slider-view', ].filter( Boolean ).join( ' ' ); const blockWrapperClassName = [ "advgb-products-wrapper", viewType === 'normal' && `columns-${columns}`, ].filter( Boolean ).join( ' ' ); return ( setAttributes( { status: value } ) } /> setAttributes( { category: value } ) } /> {category === 'selected' &&
{categoriesList.map( (cat, index) => ( ({cat.count}) ] } checked={ jQuery.inArray(cat.id, categories) > -1 } onChange={ (checked) => this.setCategories( cat.id, checked ) } /> ) ) }
}
{viewType !== 'slider' && setAttributes( { columns: value } ) } /> } setAttributes( { numberOfProducts: value } ) } /> { const splitedVal = value.split('-'); return setAttributes( { orderBy: splitedVal[0], order: splitedVal[1], } ) } } />
{!error ? !loading ? productsList.length > 0 ?
{productsList.map( (product, idx) => (
{product.name}
{ product.name }
{ __( 'Add to cart' ) }
) ) }
: ( // When no products found
{ __( 'No products found.' ) }
) : ( // When products is fetching
{ __( 'Loading' ) }
) : ( // When error
{ __( 'WooCommerce has not been detected, make sure WooCommerce is installed and activated.' ) }
) }
) } } registerBlockType( 'advgb/woo-products', { title: __( 'Woo Products' ), description: __( 'Listing your products in a easy way.' ), icon: { src: advProductsBlockIcon, foreground: typeof advgbBlocks !== 'undefined' ? advgbBlocks.color : undefined, }, category: 'advgb-category', keywords: [ __( 'woo commerce' ), __( 'products list' ), __( 'price list' ) ], attributes: { viewType: { type: 'string', default: 'normal', }, category: { type: 'string', }, categories: { type: 'array', default: [], }, status: { type: 'string', }, order: { type: 'string', default: 'desc', }, orderBy: { type: 'string', default: 'date', }, numberOfProducts: { type: 'number', default: 6, }, columns: { type: 'number', default: 3, }, changed: { type: 'boolean', default: false, } }, edit: AdvProductsEdit, save: function ( { attributes } ) { const { viewType, category, categories, status, order, orderBy, numberOfProducts, columns, } = attributes; const listCats = categories.join(','); const shortCode = [ '[products', `limit="${numberOfProducts}"`, `columns="${columns}"`, `orderby="${orderBy}"`, `order="${order}"`, category === 'selected' && `category="${listCats}"`, status === 'featured' && 'featured="1"', status === 'on_sale' && 'on_sale="1"', ']', ].filter( Boolean ).join( ' ' ); const blockClassName = [ 'advgb-woo-products', viewType === 'slider' && 'slider-view', ].filter( Boolean ).join( ' ' ); return (
{shortCode}
); } } ) } )( wp.i18n, wp.blocks, wp.element, wp.editor, wp.components );