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

Commit

Permalink
move from class to functional component
Browse files Browse the repository at this point in the history
  • Loading branch information
Sidsector9 committed Jun 16, 2023
1 parent dca174b commit e81ad0c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 123 deletions.
204 changes: 86 additions & 118 deletions assets/js/blocks/products/all-products/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ import {
InnerBlocks,
InspectorControls,
} from '@wordpress/block-editor';
import { withDispatch, withSelect } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';
import {
PanelBody,
withSpokenMessages,
Placeholder,
Button,
ToolbarGroup,
Disabled,
Tip,
} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { useState, useEffect } from '@wordpress/element';
import { useDebounce } from '@wordpress/compose';
import { Icon, grid } from '@wordpress/icons';
import GridLayoutControl from '@woocommerce/editor-components/grid-layout-control';
import {
Expand All @@ -30,6 +29,7 @@ import { getBlockMap } from '@woocommerce/atomic-utils';
import { previewProducts } from '@woocommerce/resource-previews';
import { getSetting } from '@woocommerce/settings';
import { blocksConfig } from '@woocommerce/block-settings';
import { speak } from '@wordpress/a11y';

/**
* Internal dependencies
Expand All @@ -47,63 +47,58 @@ import { getSharedContentControls, getSharedListControls } from '../edit';
import Block from './block';
import './editor.scss';

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

interface EditorProps {
block: BlockInstance;
attributes: EditorAttributes;
debouncedSpeak: ( label: string ) => void;
type Props = {
contentVisibility: number;
orderby: number;
isPreview: number;
clientId: string;
attributes: Attributes;
setAttributes: ( attributes: Record< string, unknown > ) => void;
replaceInnerBlocks: (
rootClientId: string,
blocks: BlockInstance[],
updateSelection?: boolean
) => void;
}
};

interface EditorState {
isEditing: boolean;
innerBlocks: BlockInstance[];
}
export const Edit = ( props: Props ): JSX.Element => {
const [ isEditing, setIsEditing ] = useState< boolean >( false );
const [ , setInnerBlocks ] = useState< BlockInstance[] | boolean >( false );
const blockMap = getBlockMap( 'woocommerce/all-products' );

/**
* Component to handle edit mode of "All Products".
*/
class Editor extends Component< EditorProps, EditorState > {
state = {
isEditing: false,
innerBlocks: [],
};
const { clientId, attributes, setAttributes } = props;

blockMap = getBlockMap( 'woocommerce/all-products' );
const { columns, rows, alignButtons, layoutConfig } = attributes;

componentDidMount = (): void => {
const { block } = this.props;
this.setState( { innerBlocks: block.innerBlocks } );
};
const { innerBlocks } = useSelect( ( select ) => {
const { getBlock } = select( 'core/block-editor' );
const block = getBlock( clientId );
return {
innerBlocks: block ? block.innerBlocks : [],
};
} );

useEffect( () => {
setInnerBlocks( innerBlocks );
}, [] );

const { replaceInnerBlocks } = useDispatch( 'core/block-editor' );
const debouncedSpeak = useDebounce( speak );

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

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

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

this.setState( { isEditing: ! this.state.isEditing } );

if ( ! this.state.isEditing ) {
if ( ! isEditing ) {
debouncedSpeak(
__(
'Showing All Products block preview.',
Expand All @@ -113,10 +108,7 @@ class Editor extends Component< EditorProps, EditorState > {
}
};

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

const getInspectorControls = (): JSX.Element => {
return (
<InspectorControls key="inspector">
<PanelBody
Expand All @@ -131,10 +123,10 @@ class Editor extends Component< EditorProps, EditorState > {
rows={ rows }
alignButtons={ alignButtons }
setAttributes={ setAttributes }
minColumns={ getSetting( 'min_columns', 1 ) }
maxColumns={ getSetting( 'max_columns', 6 ) }
minRows={ getSetting( 'min_rows', 1 ) }
maxRows={ getSetting( 'max_rows', 6 ) }
minColumns={ getSetting( 'min_columns', 1 ) as number }
maxColumns={ getSetting( 'max_columns', 6 ) as number }
minRows={ getSetting( 'min_rows', 1 ) as number }
maxRows={ getSetting( 'max_rows', 6 ) as number }
/>
</PanelBody>
<PanelBody
Expand All @@ -150,9 +142,7 @@ class Editor extends Component< EditorProps, EditorState > {
);
};

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

const getBlockControls = (): JSX.Element => {
return (
<BlockControls>
<ToolbarGroup
Expand All @@ -163,7 +153,7 @@ class Editor extends Component< EditorProps, EditorState > {
'Edit the layout of each product',
'woo-gutenberg-products-block'
),
onClick: () => this.togglePreview(),
onClick: () => togglePreview(),
isActive: isEditing,
},
] }
Expand All @@ -172,47 +162,47 @@ class Editor extends Component< EditorProps, EditorState > {
);
};

renderEditMode = () => {
const renderEditMode = () => {
const onDone = () => {
const { block, setAttributes } = this.props;
setAttributes( {
layoutConfig: getProductLayoutConfig( block.innerBlocks ),
layoutConfig: getProductLayoutConfig( innerBlocks ),
} );
this.setState( { innerBlocks: block.innerBlocks } );
this.togglePreview();
setInnerBlocks( innerBlocks );
togglePreview();
};

const onCancel = () => {
const { block, replaceInnerBlocks } = this.props;
const { innerBlocks } = this.state;
replaceInnerBlocks( block.clientId, innerBlocks, false );
this.togglePreview();
replaceInnerBlocks( clientId, innerBlocks, false );
togglePreview();
};

const onReset = () => {
const { block, replaceInnerBlocks } = this.props;
const newBlocks: BlockInstance[] = [];
DEFAULT_PRODUCT_LIST_LAYOUT.map( ( [ name, attributes ] ) => {
newBlocks.push( createBlock( name, attributes ) );
DEFAULT_PRODUCT_LIST_LAYOUT.map( ( [ name, blockAttributes ] ) => {
newBlocks.push( createBlock( name, blockAttributes ) );
return true;
} );
replaceInnerBlocks( block.clientId, newBlocks, false );
this.setState( { innerBlocks: block.innerBlocks } );
replaceInnerBlocks( clientId, newBlocks, false );
setInnerBlocks( innerBlocks );
};

const InnerBlockProps = {
template: this.props.attributes.layoutConfig,
const InnerBlockProps: {
template: [ string, object? ][];
templateLock: boolean;
allowedBlocks: Array< string >;
renderAppender?: undefined | boolean;
} = {
template: layoutConfig,
templateLock: false,
allowedBlocks: Object.keys( this.blockMap ),
renderAppender: true,
allowedBlocks: Object.keys( blockMap ),
};

if ( this.props.attributes.layoutConfig.length !== 0 ) {
if ( layoutConfig.length !== 0 ) {
InnerBlockProps.renderAppender = false;
}

return (
<Placeholder icon={ this.getIcon() } label={ this.getTitle() }>
<Placeholder icon={ getIcon() } label={ getTitle() }>
{ __(
'Display all products from your store as a grid.',
'woo-gutenberg-products-block'
Expand Down Expand Up @@ -277,12 +267,10 @@ class Editor extends Component< EditorProps, EditorState > {
);
};

renderViewMode = () => {
const { attributes } = this.props;
const { layoutConfig } = attributes;
const renderViewMode = () => {
const hasContent = layoutConfig && layoutConfig.length !== 0;
const blockTitle = this.getTitle();
const blockIcon = this.getIcon();
const blockTitle = getTitle();
const blockIcon = getIcon();

if ( ! hasContent ) {
return renderHiddenContentPlaceholder( blockTitle, blockIcon );
Expand All @@ -296,43 +284,23 @@ class Editor extends Component< EditorProps, EditorState > {
);
};

render = () => {
const { attributes } = this.props;
const { isEditing } = this.state;
const blockTitle = this.getTitle();
const blockIcon = this.getIcon();
const blockTitle = getTitle();
const blockIcon = getIcon();

if ( blocksConfig.productCount === 0 ) {
return renderNoProductsPlaceholder( blockTitle, blockIcon );
}

return (
<div
className={ getBlockClassName(
'wc-block-all-products',
attributes
) }
>
{ this.getBlockControls() }
{ this.getInspectorControls() }
{ isEditing ? this.renderEditMode() : this.renderViewMode() }
</div>
);
};
}
if ( blocksConfig.productCount === 0 ) {
return renderNoProductsPlaceholder( blockTitle, blockIcon );
}

export default compose(
withSpokenMessages,
withSelect( ( select, { clientId } ) => {
const { getBlock } = select( 'core/block-editor' );
return {
block: getBlock( clientId ),
};
} ),
withDispatch( ( dispatch ) => {
const { replaceInnerBlocks } = dispatch( 'core/block-editor' );
return {
replaceInnerBlocks,
};
} )
)( Editor );
return (
<div
className={ getBlockClassName(
'wc-block-all-products',
attributes
) }
>
{ getBlockControls() }
{ getInspectorControls() }
{ isEditing ? renderEditMode() : renderViewMode() }
</div>
);
};
8 changes: 4 additions & 4 deletions assets/js/blocks/products/all-products/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import '@woocommerce/atomic-blocks';
*/
import metadata from './block.json';
import deprecated from './deprecated';
import edit from './edit';
import save from './save';
import { Edit } from './edit';
import Save from './save';
import defaults from './defaults';

const { name } = metadata;
Expand All @@ -26,9 +26,9 @@ const settings = {
/>
),
},
edit,
edit: Edit,
// Save the props to post content.
save,
save: Save,
deprecated,
defaults,
};
Expand Down
2 changes: 1 addition & 1 deletion assets/js/blocks/products/all-products/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { InnerBlocks } from '@wordpress/block-editor';
*/
import { getBlockClassName } from '../utils.js';

export default function save( { attributes } ) {
export default function Save( { attributes } ) {
const dataAttributes = {};
Object.keys( attributes )
.sort()
Expand Down

0 comments on commit e81ad0c

Please sign in to comment.