Product Collection - refactor inspector controls props (https://github.com/woocommerce/woocommerce-blocks/pull/10154)

* Refactor Columns Control inspector controls in Product Collection

* Refactor Order By inspector controls in Product Collection

* Reorder imports in Product Collection Inspector Controls

* Refactor On Sale inspector controls in Product Collection

* Refactor Stock Status inspector controls in Product Collection

* Refactor Keyword inspector controls in Product Collection

* Unify interface of query controlling Inspector Controls

* Unify interfaces of Inspector Controls that modify Query in Product Collection

* Unify other Query modifying Controls

* Simplify types
This commit is contained in:
Karol Manijak 2023-07-11 13:05:49 +02:00 committed by GitHub
parent d4c3d43f9d
commit c55343b736
12 changed files with 99 additions and 140 deletions

View File

@ -61,17 +61,23 @@ export const DEFAULT_ATTRIBUTES: Partial< ProductCollectionAttributes > = {
},
};
export const getDefaultQuery = (
currentQuery: ProductCollectionQuery
): ProductCollectionQuery => ( {
...currentQuery,
orderBy: DEFAULT_QUERY.orderBy as TProductCollectionOrderBy,
order: DEFAULT_QUERY.order as TProductCollectionOrder,
inherit: DEFAULT_QUERY.inherit,
} );
export const getDefaultDisplayLayout = () =>
DEFAULT_ATTRIBUTES.displayLayout as ProductCollectionDisplayLayout;
export const getDefaultSettings = (
currentAttributes: ProductCollectionAttributes
): Partial< ProductCollectionAttributes > => ( {
displayLayout:
DEFAULT_ATTRIBUTES.displayLayout as ProductCollectionDisplayLayout,
query: {
...currentAttributes.query,
orderBy: DEFAULT_QUERY.orderBy as TProductCollectionOrderBy,
order: DEFAULT_QUERY.order as TProductCollectionOrder,
inherit: DEFAULT_QUERY.inherit,
},
displayLayout: getDefaultDisplayLayout(),
query: getDefaultQuery( currentAttributes.query ),
} );
export const DEFAULT_FILTERS: Partial< ProductCollectionQuery > = {

View File

@ -3,7 +3,6 @@
*/
import { __ } from '@wordpress/i18n';
import ProductAttributeTermControl from '@woocommerce/editor-components/product-attribute-term-control';
import { AttributeMetadata } from '@woocommerce/types';
import { SearchListItem } from '@woocommerce/editor-components/search-list-control/types';
import { ADMIN_URL } from '@woocommerce/settings';
import {
@ -16,19 +15,15 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionQuery } from '../types';
import { QueryControlProps } from '../types';
const EDIT_ATTRIBUTES_URL = `${ ADMIN_URL }edit.php?post_type=product&page=product_attributes`;
interface AttributesControlProps {
woocommerceAttributes?: AttributeMetadata[];
setQueryAttribute: ( value: Partial< ProductCollectionQuery > ) => void;
}
const AttributesControl = ( {
woocommerceAttributes,
query,
setQueryAttribute,
}: AttributesControlProps ) => {
}: QueryControlProps ) => {
const woocommerceAttributes = query.woocommerceAttributes || [];
const selectedAttributes = woocommerceAttributes?.map(
( { termId: id } ) => ( {
id,

View File

@ -13,7 +13,7 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionQuery } from '../types';
import { QueryControlProps } from '../types';
interface Author {
id: string;
@ -27,11 +27,6 @@ interface AuthorsInfo {
names: string[];
}
interface AuthorControlProps {
value: string;
setQueryAttribute: ( value: Partial< ProductCollectionQuery > ) => void;
}
const AUTHORS_QUERY = {
who: 'authors',
per_page: -1,
@ -68,7 +63,8 @@ const getIdByValue = (
if ( id ) return id;
};
function AuthorControl( { value, setQueryAttribute }: AuthorControlProps ) {
function AuthorControl( { query, setQueryAttribute }: QueryControlProps ) {
const value = query.author;
const { records: authorsList, error } = useEntityRecords< Author[] >(
'root',
'user',

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks';
import {
RangeControl,
// @ts-expect-error Using experimental features
@ -13,32 +12,26 @@ import {
/**
* Internal dependencies
*/
import {
ProductCollectionAttributes,
ProductCollectionDisplayLayout,
} from '../types';
import { getDefaultSettings } from '../constants';
import { DisplayLayoutControlProps } from '../types';
import { getDefaultDisplayLayout } from '../constants';
const ColumnsControl = (
props: BlockEditProps< ProductCollectionAttributes >
) => {
const { type, columns } = props.attributes.displayLayout;
const ColumnsControl = ( props: DisplayLayoutControlProps ) => {
const { type, columns } = props.displayLayout;
const showColumnsControl = type === 'flex';
const defaultSettings = getDefaultSettings( props.attributes );
const defaultLayout = getDefaultDisplayLayout();
return showColumnsControl ? (
<ToolsPanelItem
label={ __( 'Columns', 'woo-gutenberg-products-block' ) }
hasValue={ () =>
defaultSettings.displayLayout?.columns !== columns ||
defaultSettings.displayLayout?.type !== type
defaultLayout?.columns !== columns ||
defaultLayout?.type !== type
}
isShownByDefault
onDeselect={ () => {
props.setAttributes( {
displayLayout:
defaultSettings.displayLayout as ProductCollectionDisplayLayout,
displayLayout: defaultLayout,
} );
} }
>
@ -48,7 +41,7 @@ const ColumnsControl = (
onChange={ ( value: number ) =>
props.setAttributes( {
displayLayout: {
...props.attributes.displayLayout,
...props.displayLayout,
columns: value,
},
} )

View File

@ -8,15 +8,10 @@ import { list, grid } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { ProductCollectionDisplayLayout } from '../types';
type DisplayLayoutObject = {
displayLayout: ProductCollectionDisplayLayout;
};
type DisplayLayoutControlProps = DisplayLayoutObject & {
setAttributes: ( attrs: DisplayLayoutObject ) => void;
};
import {
DisplayLayoutControlProps,
ProductCollectionDisplayLayout,
} from '../types';
const DisplayLayoutControl = ( props: DisplayLayoutControlProps ) => {
const { type, columns } = props.displayLayout;

View File

@ -15,12 +15,7 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionQuery } from '../types';
interface HandPickedProductsControlProps {
setQueryAttribute: ( value: Partial< ProductCollectionQuery > ) => void;
selectedProductIds?: string[] | undefined;
}
import { QueryControlProps } from '../types';
/**
* Returns:
@ -55,9 +50,10 @@ function useProducts() {
}
const HandPickedProductsControl = ( {
selectedProductIds,
query,
setQueryAttribute,
}: HandPickedProductsControlProps ) => {
}: QueryControlProps ) => {
const selectedProductIds = query.woocommerceHandPickedProducts;
const { productsMap, productsList } = useProducts();
const onTokenChange = useCallback(

View File

@ -16,12 +16,12 @@ import {
* Internal dependencies
*/
import { ProductCollectionAttributes } from '../types';
import { setQueryAttribute } from '../utils';
import { DEFAULT_FILTERS, getDefaultSettings } from '../constants';
import ColumnsControl from './columns-control';
import InheritQueryControl from './inherit-query-control';
import OrderByControl from './order-by-control';
import OnSaleControl from './on-sale-control';
import { setQueryAttribute } from '../utils';
import { DEFAULT_FILTERS, getDefaultSettings } from '../constants';
import StockStatusControl from './stock-status-control';
import KeywordControl from './keyword-control';
import AttributesControl from './attributes-control';
@ -42,13 +42,20 @@ const ProductCollectionInspectorControls = (
[ props ]
);
const displayControlProps = {
setAttributes: props.setAttributes,
displayLayout: props.attributes.displayLayout,
};
const queryControlProps = {
setQueryAttribute: setQueryAttributeBind,
query,
};
return (
<InspectorControls>
<BlockControls>
<DisplayLayoutControl
displayLayout={ props.attributes.displayLayout }
setAttributes={ props.setAttributes }
/>
<DisplayLayoutControl { ...displayControlProps } />
</BlockControls>
<ToolsPanel
label={ __( 'Settings', 'woo-gutenberg-products-block' ) }
@ -59,13 +66,10 @@ const ProductCollectionInspectorControls = (
props.setAttributes( defaultSettings );
} }
>
<ColumnsControl { ...props } />
<InheritQueryControl
setQueryAttribute={ setQueryAttributeBind }
query={ query }
/>
<ColumnsControl { ...displayControlProps } />
<InheritQueryControl { ...queryControlProps } />
{ displayQueryControls ? (
<OrderByControl { ...props } />
<OrderByControl { ...queryControlProps } />
) : null }
</ToolsPanel>
@ -80,29 +84,13 @@ const ProductCollectionInspectorControls = (
} }
className="wc-block-editor-product-collection-inspector-toolspanel__filters"
>
<OnSaleControl { ...props } />
<StockStatusControl { ...props } />
<HandPickedProductsControl
setQueryAttribute={ setQueryAttributeBind }
selectedProductIds={
query.woocommerceHandPickedProducts
}
/>
<KeywordControl { ...props } />
<AttributesControl
woocommerceAttributes={
query.woocommerceAttributes || []
}
setQueryAttribute={ setQueryAttributeBind }
/>
<TaxonomyControls
setQueryAttribute={ setQueryAttributeBind }
query={ query }
/>
<AuthorControl
value={ query.author }
setQueryAttribute={ setQueryAttributeBind }
/>
<OnSaleControl { ...queryControlProps } />
<StockStatusControl { ...queryControlProps } />
<HandPickedProductsControl { ...queryControlProps } />
<KeywordControl { ...queryControlProps } />
<AttributesControl { ...queryControlProps } />
<TaxonomyControls { ...queryControlProps } />
<AuthorControl { ...queryControlProps } />
</ToolsPanel>
) : null }
<ProductCollectionFeedbackPrompt />

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks';
import { useEffect, useState } from '@wordpress/element';
import { useDebounce } from '@wordpress/compose';
import {
@ -15,18 +14,17 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionAttributes } from '../types';
import { setQueryAttribute } from '../utils';
import { QueryControlProps } from '../types';
const KeywordControl = (
props: BlockEditProps< ProductCollectionAttributes >
) => {
const { query } = props.attributes;
const KeywordControl = ( props: QueryControlProps ) => {
const { query, setQueryAttribute } = props;
const [ querySearch, setQuerySearch ] = useState( query.search );
const onChangeDebounced = useDebounce( () => {
if ( query.search !== querySearch ) {
setQueryAttribute( props, { search: querySearch } );
setQueryAttribute( {
search: querySearch,
} );
}
}, 250 );

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks';
import {
ToggleControl,
// @ts-expect-error Using experimental features
@ -13,13 +12,10 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionAttributes } from '../types';
import { setQueryAttribute } from '../utils';
import { QueryControlProps } from '../types';
const OnSaleControl = (
props: BlockEditProps< ProductCollectionAttributes >
) => {
const { query } = props.attributes;
const OnSaleControl = ( props: QueryControlProps ) => {
const { query, setQueryAttribute } = props;
return (
<ToolsPanelItem
@ -27,7 +23,7 @@ const OnSaleControl = (
hasValue={ () => query.woocommerceOnSale === true }
isShownByDefault
onDeselect={ () => {
setQueryAttribute( props, {
setQueryAttribute( {
woocommerceOnSale: false,
} );
} }
@ -39,7 +35,7 @@ const OnSaleControl = (
) }
checked={ query.woocommerceOnSale || false }
onChange={ ( woocommerceOnSale ) => {
setQueryAttribute( props, {
setQueryAttribute( {
woocommerceOnSale,
} );
} }

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks';
import {
SelectControl,
// @ts-expect-error Using experimental features
@ -14,11 +13,11 @@ import {
* Internal dependencies
*/
import {
ProductCollectionAttributes,
TProductCollectionOrder,
TProductCollectionOrderBy,
QueryControlProps,
} from '../types';
import { getDefaultSettings } from '../constants';
import { getDefaultQuery } from '../constants';
const orderOptions = [
{
@ -47,27 +46,21 @@ const orderOptions = [
},
];
const OrderByControl = (
props: BlockEditProps< ProductCollectionAttributes >
) => {
const { order, orderBy } = props.attributes.query;
const defaultSettings = getDefaultSettings( props.attributes );
const OrderByControl = ( props: QueryControlProps ) => {
const { query, setQueryAttribute } = props;
const { order, orderBy } = query;
const defaultQuery = getDefaultQuery( query );
return (
<ToolsPanelItem
label={ __( 'Order by', 'woo-gutenberg-products-block' ) }
hasValue={ () =>
order !== defaultSettings.query?.order ||
orderBy !== defaultSettings.query?.orderBy
order !== defaultQuery?.order ||
orderBy !== defaultQuery?.orderBy
}
isShownByDefault
onDeselect={ () => {
props.setAttributes( {
query: {
...props.attributes.query,
...defaultSettings.query,
},
} );
setQueryAttribute( defaultQuery );
} }
>
<SelectControl
@ -76,12 +69,9 @@ const OrderByControl = (
label={ __( 'Order by', 'woo-gutenberg-products-block' ) }
onChange={ ( value ) => {
const [ newOrderBy, newOrder ] = value.split( '/' );
props.setAttributes( {
query: {
...props.attributes.query,
order: newOrder as TProductCollectionOrder,
orderBy: newOrderBy as TProductCollectionOrderBy,
},
setQueryAttribute( {
order: newOrder as TProductCollectionOrder,
orderBy: newOrderBy as TProductCollectionOrderBy,
} );
} }
/>

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps } from '@wordpress/blocks';
import fastDeepEqual from 'fast-deep-equal/es6';
import {
FormTokenField,
@ -14,8 +13,7 @@ import {
/**
* Internal dependencies
*/
import { ProductCollectionAttributes } from '../types';
import { setQueryAttribute } from '../utils';
import { QueryControlProps } from '../types';
import { STOCK_STATUS_OPTIONS, getDefaultStockStatuses } from '../constants';
/**
@ -35,10 +33,9 @@ function getStockStatusIdByLabel( statusLabel: FormTokenField.Value ) {
)?.[ 0 ];
}
const StockStatusControl = (
props: BlockEditProps< ProductCollectionAttributes >
) => {
const { query } = props.attributes;
const StockStatusControl = ( props: QueryControlProps ) => {
const { query, setQueryAttribute } = props;
return (
<ToolsPanelItem
label={ __( 'Stock status', 'woo-gutenberg-products-block' ) }
@ -49,7 +46,7 @@ const StockStatusControl = (
)
}
onDeselect={ () => {
setQueryAttribute( props, {
setQueryAttribute( {
woocommerceStockStatus: getDefaultStockStatuses(),
} );
} }
@ -62,7 +59,7 @@ const StockStatusControl = (
.map( getStockStatusIdByLabel )
.filter( Boolean ) as string[];
setQueryAttribute( props, {
setQueryAttribute( {
woocommerceStockStatus,
} );
} }

View File

@ -61,3 +61,12 @@ export type TProductCollectionOrderBy =
| 'title'
| 'popularity'
| 'rating';
export type DisplayLayoutControlProps = {
displayLayout: ProductCollectionDisplayLayout;
setAttributes: ( attrs: Partial< ProductCollectionAttributes > ) => void;
};
export type QueryControlProps = {
query: ProductCollectionQuery;
setQueryAttribute: ( attrs: Partial< ProductCollectionQuery > ) => void;
};