@@ -8,18 +8,17 @@ import {
88 InnerBlocks ,
99 InspectorControls ,
1010} from '@wordpress/block-editor' ;
11- import { withDispatch , withSelect } from '@wordpress/data' ;
11+ import { useSelect , useDispatch } from '@wordpress/data' ;
1212import {
1313 PanelBody ,
14- withSpokenMessages ,
1514 Placeholder ,
1615 Button ,
1716 ToolbarGroup ,
1817 Disabled ,
1918 Tip ,
2019} from '@wordpress/components' ;
21- import { Component } from '@wordpress/element' ;
22- import { compose } from '@wordpress/compose' ;
20+ import { useState , useEffect } from '@wordpress/element' ;
21+ import { useDebounce } from '@wordpress/compose' ;
2322import { Icon , grid } from '@wordpress/icons' ;
2423import GridLayoutControl from '@woocommerce/editor-components/grid-layout-control' ;
2524import {
@@ -30,6 +29,7 @@ import { getBlockMap } from '@woocommerce/atomic-utils';
3029import { previewProducts } from '@woocommerce/resource-previews' ;
3130import { getSetting } from '@woocommerce/settings' ;
3231import { blocksConfig } from '@woocommerce/block-settings' ;
32+ import { speak } from '@wordpress/a11y' ;
3333
3434/**
3535 * Internal dependencies
@@ -47,63 +47,58 @@ import { getSharedContentControls, getSharedListControls } from '../edit';
4747import Block from './block' ;
4848import './editor.scss' ;
4949
50- type EditorAttributes = {
50+ type Attributes = {
5151 columns : number ;
5252 rows : number ;
5353 alignButtons : boolean ;
54- contentVisibility : object ;
55- orderby : string ;
56- layoutConfig : Array < object > ;
57- isPreview : boolean ;
54+ layoutConfig : [ string , object ? ] [ ] ;
5855} ;
5956
60- interface EditorProps {
61- block : BlockInstance ;
62- attributes : EditorAttributes ;
63- debouncedSpeak : ( label : string ) => void ;
57+ type Props = {
58+ contentVisibility : number ;
59+ orderby : number ;
60+ isPreview : number ;
61+ clientId : string ;
62+ attributes : Attributes ;
6463 setAttributes : ( attributes : Record < string , unknown > ) => void ;
65- replaceInnerBlocks : (
66- rootClientId : string ,
67- blocks : BlockInstance [ ] ,
68- updateSelection ?: boolean
69- ) => void ;
70- }
64+ } ;
7165
72- interface EditorState {
73- isEditing : boolean ;
74- innerBlocks : BlockInstance [ ] ;
75- }
66+ export const Edit = ( props : Props ) : JSX . Element => {
67+ const [ isEditing , setIsEditing ] = useState < boolean > ( false ) ;
68+ const [ , setInnerBlocks ] = useState < BlockInstance [ ] | boolean > ( false ) ;
69+ const blockMap = getBlockMap ( 'woocommerce/all-products' ) ;
7670
77- /**
78- * Component to handle edit mode of "All Products".
79- */
80- class Editor extends Component < EditorProps , EditorState > {
81- state = {
82- isEditing : false ,
83- innerBlocks : [ ] ,
84- } ;
71+ const { clientId, attributes, setAttributes } = props ;
8572
86- blockMap = getBlockMap ( 'woocommerce/all-products' ) ;
73+ const { columns , rows , alignButtons , layoutConfig } = attributes ;
8774
88- componentDidMount = ( ) : void => {
89- const { block } = this . props ;
90- this . setState ( { innerBlocks : block . innerBlocks } ) ;
91- } ;
75+ const { innerBlocks } = useSelect ( ( select ) => {
76+ const { getBlock } = select ( 'core/block-editor' ) ;
77+ const block = getBlock ( clientId ) ;
78+ return {
79+ innerBlocks : block ? block . innerBlocks : [ ] ,
80+ } ;
81+ } ) ;
82+
83+ useEffect ( ( ) => {
84+ setInnerBlocks ( innerBlocks ) ;
85+ } , [ ] ) ;
86+
87+ const { replaceInnerBlocks } = useDispatch ( 'core/block-editor' ) ;
88+ const debouncedSpeak = useDebounce ( speak ) ;
9289
93- getTitle = ( ) : string => {
90+ const getTitle = ( ) : string => {
9491 return __ ( 'All Products' , 'woo-gutenberg-products-block' ) ;
9592 } ;
9693
97- getIcon = ( ) : JSX . Element => {
94+ const getIcon = ( ) : JSX . Element => {
9895 return < Icon icon = { grid } /> ;
9996 } ;
10097
101- togglePreview = ( ) : void => {
102- const { debouncedSpeak } = this . props ;
98+ const togglePreview = ( ) : void => {
99+ setIsEditing ( ! isEditing ) ;
103100
104- this . setState ( { isEditing : ! this . state . isEditing } ) ;
105-
106- if ( ! this . state . isEditing ) {
101+ if ( ! isEditing ) {
107102 debouncedSpeak (
108103 __ (
109104 'Showing All Products block preview.' ,
@@ -113,10 +108,7 @@ class Editor extends Component< EditorProps, EditorState > {
113108 }
114109 } ;
115110
116- getInspectorControls = ( ) : JSX . Element => {
117- const { attributes, setAttributes } = this . props ;
118- const { columns, rows, alignButtons } = attributes ;
119-
111+ const getInspectorControls = ( ) : JSX . Element => {
120112 return (
121113 < InspectorControls key = "inspector" >
122114 < PanelBody
@@ -131,10 +123,10 @@ class Editor extends Component< EditorProps, EditorState > {
131123 rows = { rows }
132124 alignButtons = { alignButtons }
133125 setAttributes = { setAttributes }
134- minColumns = { getSetting ( 'min_columns' , 1 ) }
135- maxColumns = { getSetting ( 'max_columns' , 6 ) }
136- minRows = { getSetting ( 'min_rows' , 1 ) }
137- maxRows = { getSetting ( 'max_rows' , 6 ) }
126+ minColumns = { getSetting ( 'min_columns' , 1 ) as number }
127+ maxColumns = { getSetting ( 'max_columns' , 6 ) as number }
128+ minRows = { getSetting ( 'min_rows' , 1 ) as number }
129+ maxRows = { getSetting ( 'max_rows' , 6 ) as number }
138130 />
139131 </ PanelBody >
140132 < PanelBody
@@ -150,9 +142,7 @@ class Editor extends Component< EditorProps, EditorState > {
150142 ) ;
151143 } ;
152144
153- getBlockControls = ( ) : JSX . Element => {
154- const { isEditing } = this . state ;
155-
145+ const getBlockControls = ( ) : JSX . Element => {
156146 return (
157147 < BlockControls >
158148 < ToolbarGroup
@@ -163,7 +153,7 @@ class Editor extends Component< EditorProps, EditorState > {
163153 'Edit the layout of each product' ,
164154 'woo-gutenberg-products-block'
165155 ) ,
166- onClick : ( ) => this . togglePreview ( ) ,
156+ onClick : ( ) => togglePreview ( ) ,
167157 isActive : isEditing ,
168158 } ,
169159 ] }
@@ -172,47 +162,47 @@ class Editor extends Component< EditorProps, EditorState > {
172162 ) ;
173163 } ;
174164
175- renderEditMode = ( ) => {
165+ const renderEditMode = ( ) => {
176166 const onDone = ( ) => {
177- const { block, setAttributes } = this . props ;
178167 setAttributes ( {
179- layoutConfig : getProductLayoutConfig ( block . innerBlocks ) ,
168+ layoutConfig : getProductLayoutConfig ( innerBlocks ) ,
180169 } ) ;
181- this . setState ( { innerBlocks : block . innerBlocks } ) ;
182- this . togglePreview ( ) ;
170+ setInnerBlocks ( innerBlocks ) ;
171+ togglePreview ( ) ;
183172 } ;
184173
185174 const onCancel = ( ) => {
186- const { block, replaceInnerBlocks } = this . props ;
187- const { innerBlocks } = this . state ;
188- replaceInnerBlocks ( block . clientId , innerBlocks , false ) ;
189- this . togglePreview ( ) ;
175+ replaceInnerBlocks ( clientId , innerBlocks , false ) ;
176+ togglePreview ( ) ;
190177 } ;
191178
192179 const onReset = ( ) => {
193- const { block, replaceInnerBlocks } = this . props ;
194180 const newBlocks : BlockInstance [ ] = [ ] ;
195- DEFAULT_PRODUCT_LIST_LAYOUT . map ( ( [ name , attributes ] ) => {
196- newBlocks . push ( createBlock ( name , attributes ) ) ;
181+ DEFAULT_PRODUCT_LIST_LAYOUT . map ( ( [ name , blockAttributes ] ) => {
182+ newBlocks . push ( createBlock ( name , blockAttributes ) ) ;
197183 return true ;
198184 } ) ;
199- replaceInnerBlocks ( block . clientId , newBlocks , false ) ;
200- this . setState ( { innerBlocks : block . innerBlocks } ) ;
185+ replaceInnerBlocks ( clientId , newBlocks , false ) ;
186+ setInnerBlocks ( innerBlocks ) ;
201187 } ;
202188
203- const InnerBlockProps = {
204- template : this . props . attributes . layoutConfig ,
189+ const InnerBlockProps : {
190+ template : [ string , object ? ] [ ] ;
191+ templateLock : boolean ;
192+ allowedBlocks : Array < string > ;
193+ renderAppender ?: undefined | boolean ;
194+ } = {
195+ template : layoutConfig ,
205196 templateLock : false ,
206- allowedBlocks : Object . keys ( this . blockMap ) ,
207- renderAppender : true ,
197+ allowedBlocks : Object . keys ( blockMap ) ,
208198 } ;
209199
210- if ( this . props . attributes . layoutConfig . length !== 0 ) {
200+ if ( layoutConfig . length !== 0 ) {
211201 InnerBlockProps . renderAppender = false ;
212202 }
213203
214204 return (
215- < Placeholder icon = { this . getIcon ( ) } label = { this . getTitle ( ) } >
205+ < Placeholder icon = { getIcon ( ) } label = { getTitle ( ) } >
216206 { __ (
217207 'Display all products from your store as a grid.' ,
218208 'woo-gutenberg-products-block'
@@ -277,12 +267,10 @@ class Editor extends Component< EditorProps, EditorState > {
277267 ) ;
278268 } ;
279269
280- renderViewMode = ( ) => {
281- const { attributes } = this . props ;
282- const { layoutConfig } = attributes ;
270+ const renderViewMode = ( ) => {
283271 const hasContent = layoutConfig && layoutConfig . length !== 0 ;
284- const blockTitle = this . getTitle ( ) ;
285- const blockIcon = this . getIcon ( ) ;
272+ const blockTitle = getTitle ( ) ;
273+ const blockIcon = getIcon ( ) ;
286274
287275 if ( ! hasContent ) {
288276 return renderHiddenContentPlaceholder ( blockTitle , blockIcon ) ;
@@ -296,43 +284,23 @@ class Editor extends Component< EditorProps, EditorState > {
296284 ) ;
297285 } ;
298286
299- render = ( ) => {
300- const { attributes } = this . props ;
301- const { isEditing } = this . state ;
302- const blockTitle = this . getTitle ( ) ;
303- const blockIcon = this . getIcon ( ) ;
287+ const blockTitle = getTitle ( ) ;
288+ const blockIcon = getIcon ( ) ;
304289
305- if ( blocksConfig . productCount === 0 ) {
306- return renderNoProductsPlaceholder ( blockTitle , blockIcon ) ;
307- }
308-
309- return (
310- < div
311- className = { getBlockClassName (
312- 'wc-block-all-products' ,
313- attributes
314- ) }
315- >
316- { this . getBlockControls ( ) }
317- { this . getInspectorControls ( ) }
318- { isEditing ? this . renderEditMode ( ) : this . renderViewMode ( ) }
319- </ div >
320- ) ;
321- } ;
322- }
290+ if ( blocksConfig . productCount === 0 ) {
291+ return renderNoProductsPlaceholder ( blockTitle , blockIcon ) ;
292+ }
323293
324- export default compose (
325- withSpokenMessages ,
326- withSelect ( ( select , { clientId } ) => {
327- const { getBlock } = select ( 'core/block-editor' ) ;
328- return {
329- block : getBlock ( clientId ) ,
330- } ;
331- } ) ,
332- withDispatch ( ( dispatch ) => {
333- const { replaceInnerBlocks } = dispatch ( 'core/block-editor' ) ;
334- return {
335- replaceInnerBlocks,
336- } ;
337- } )
338- ) ( Editor ) ;
294+ return (
295+ < div
296+ className = { getBlockClassName (
297+ 'wc-block-all-products' ,
298+ attributes
299+ ) }
300+ >
301+ { getBlockControls ( ) }
302+ { getInspectorControls ( ) }
303+ { isEditing ? renderEditMode ( ) : renderViewMode ( ) }
304+ </ div >
305+ ) ;
306+ } ;
0 commit comments