Skip to content
This repository was 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
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Contributor

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
Contributor 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,
};

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