Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Convert all products edit to TypeScript #9782

Open
wants to merge 13 commits into
base: trunk
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { createBlock } from '@wordpress/blocks';
import { createBlock, BlockInstance } from '@wordpress/blocks';
import {
BlockControls,
InnerBlocks,
Expand All @@ -20,7 +20,6 @@ import {
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import PropTypes from 'prop-types';
import { Icon, grid } from '@wordpress/icons';
import GridLayoutControl from '@woocommerce/editor-components/grid-layout-control';
import {
Expand Down Expand Up @@ -48,46 +47,58 @@ import { getSharedContentControls, getSharedListControls } from '../edit';
import Block from './block';
import './editor.scss';

type EditorAttributes = {
columns: number;
rows: number;
alignButtons: boolean;
contentVisibility: object;
orderby: string;
layoutConfig: Array< object >;
isPreview: boolean;
};

interface EditorProps {
block: BlockInstance;
attributes: EditorAttributes;
debouncedSpeak: ( label: string ) => void;
setAttributes: ( attributes: Record< string, unknown > ) => void;
replaceInnerBlocks: (
rootClientId: string,
blocks: BlockInstance[],
updateSelection?: boolean
) => void;
}

interface EditorState {
isEditing: boolean;
innerBlocks: BlockInstance[];
}

/**
* Component to handle edit mode of "All Products".
*/
class Editor extends Component {
static propTypes = {
/**
* The attributes for this block.
*/
attributes: PropTypes.object.isRequired,
/**
* A callback to update attributes.
*/
setAttributes: PropTypes.func.isRequired,
/**
* From withSpokenMessages.
*/
debouncedSpeak: PropTypes.func.isRequired,
};

class Editor extends Component< EditorProps, EditorState > {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While briefly looking at your changes, I noticed that this file is still using a class component. Now that we're touching this file, we should convert it to a functional component. Could you take care of that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nielslange I've moved from class to functional component.

state = {
isEditing: false,
innerBlocks: [],
};

blockMap = getBlockMap( 'woocommerce/all-products' );

componentDidMount = () => {
componentDidMount = (): void => {
const { block } = this.props;
this.setState( { innerBlocks: block.innerBlocks } );
};

getTitle = () => {
getTitle = (): string => {
return __( 'All Products', 'woo-gutenberg-products-block' );
};

getIcon = () => {
getIcon = (): JSX.Element => {
return <Icon icon={ grid } />;
};

togglePreview = () => {
togglePreview = (): void => {
const { debouncedSpeak } = this.props;

this.setState( { isEditing: ! this.state.isEditing } );
Expand All @@ -102,7 +113,7 @@ class Editor extends Component {
}
};

getInspectorControls = () => {
getInspectorControls = (): JSX.Element => {
const { attributes, setAttributes } = this.props;
const { columns, rows, alignButtons } = attributes;

Expand Down Expand Up @@ -139,7 +150,7 @@ class Editor extends Component {
);
};

getBlockControls = () => {
getBlockControls = (): JSX.Element => {
const { isEditing } = this.state;

return (
Expand Down Expand Up @@ -180,7 +191,7 @@ class Editor extends Component {

const onReset = () => {
const { block, replaceInnerBlocks } = this.props;
const newBlocks = [];
const newBlocks: BlockInstance[] = [];
DEFAULT_PRODUCT_LIST_LAYOUT.map( ( [ name, attributes ] ) => {
newBlocks.push( createBlock( name, attributes ) );
return true;
Expand All @@ -193,6 +204,7 @@ class Editor extends Component {
template: this.props.attributes.layoutConfig,
templateLock: false,
allowedBlocks: Object.keys( this.blockMap ),
renderAppender: true,
kmanijak marked this conversation as resolved.
Show resolved Hide resolved
};

if ( this.props.attributes.layoutConfig.length !== 0 ) {
Expand Down Expand Up @@ -221,7 +233,9 @@ class Editor extends Component {
<li className="wc-block-grid__product">
<ProductDataContextProvider
product={ previewProducts[ 0 ] }
isLoading={ false }
>
{ /* @ts-expect-error: `InnerBlocks` is a component that is typed in WordPress core*/ }
<InnerBlocks { ...InnerBlockProps } />
</ProductDataContextProvider>
</li>
Expand Down Expand Up @@ -276,6 +290,7 @@ class Editor extends Component {

return (
<Disabled>
{ /* @ts-expect-error: `Block` is a component that is typed in WordPress core*/ }
<Block attributes={ attributes } />
</Disabled>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classnames from 'classnames';
import { BlockInstance } from '@wordpress/blocks';

/**
* Internal dependencies
Expand All @@ -12,7 +13,7 @@ import { ImageSizing } from '../../atomic/blocks/product-elements/image/types';
/**
* The default layout built from the default template.
*/
export const DEFAULT_PRODUCT_LIST_LAYOUT = [
export const DEFAULT_PRODUCT_LIST_LAYOUT: [ string, object? ][] = [
[ 'woocommerce/product-image', { imageSizing: ImageSizing.THUMBNAIL } ],
[ 'woocommerce/product-title' ],
[ 'woocommerce/product-price' ],
Expand All @@ -25,7 +26,9 @@ export const DEFAULT_PRODUCT_LIST_LAYOUT = [
*
* @param {Object[]} innerBlocks Inner block components.
*/
export const getProductLayoutConfig = ( innerBlocks ) => {
export const getProductLayoutConfig = (
innerBlocks: BlockInstance[]
): [ string, object? ][] => {
if ( ! innerBlocks || innerBlocks.length === 0 ) {
return [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
*/
import { __ } from '@wordpress/i18n';
import { WC_BLOCKS_IMAGE_URL } from '@woocommerce/block-settings';
import { ProductResponseItem } from '@woocommerce/types';

const shortDescription = __(
'Fly your WordPress banner with this beauty! Deck out your office space or add it to your kids walls. This banner will spruce up any space it’s hung!',
'woo-gutenberg-products-block'
);

export const previewProducts = [
export const previewProducts: Array< ProductResponseItem > = [
{
id: 1,
name: 'WordPress Pennant',
Expand All @@ -33,7 +34,7 @@ export const previewProducts = [
sizes: '',
},
],
average_rating: 5,
average_rating: '5',
categories: [
{
id: 1,
Expand All @@ -58,6 +59,10 @@ export const previewProducts = [
add_to_cart: {
text: __( 'Add to cart', 'woo-gutenberg-products-block' ),
description: __( 'Add to cart', 'woo-gutenberg-products-block' ),
url: '',
minimum: 1,
maximum: 99,
multiple_of: 1,
},
has_options: false,
is_purchasable: true,
Expand Down