From 596cbbfa17fd51b9a1ac81e42e31dd2e9bf6044f Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Thu, 2 Jun 2022 23:00:09 +1000 Subject: [PATCH 01/16] Support transforming the Facet widget to a Block. --- assets/js/blocks/facets/index.js | 12 +++++++++-- assets/js/blocks/facets/transforms.js | 25 ++++++++++++++++++++++ includes/classes/Feature/Facets/Widget.php | 6 +++++- 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 assets/js/blocks/facets/transforms.js diff --git a/assets/js/blocks/facets/index.js b/assets/js/blocks/facets/index.js index 96828bf403..1eb8cd711c 100644 --- a/assets/js/blocks/facets/index.js +++ b/assets/js/blocks/facets/index.js @@ -1,9 +1,17 @@ +/** + * WordPress dependencies. + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies. + */ import edit from './edit'; +import transforms from './transforms'; import block from './block.json'; -const { registerBlockType } = wp.blocks; - registerBlockType(block, { edit, save: () => {}, + transforms, }); diff --git a/assets/js/blocks/facets/transforms.js b/assets/js/blocks/facets/transforms.js new file mode 100644 index 0000000000..5aa1b2b197 --- /dev/null +++ b/assets/js/blocks/facets/transforms.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies. + */ +import { createBlock } from '@wordpress/blocks'; + +/** + * Facet widget block transforms. + */ +export default { + from: [ + { + type: 'block', + blocks: ['core/legacy-widget'], + isMatch: ({ idBase }) => idBase === 'ep-facet', + transform: ({ instance }) => { + const { title, ...attributes } = instance.raw; + + return [ + createBlock('core/heading', { content: title }), + createBlock('elasticpress/facet', attributes), + ]; + }, + }, + ], +}; diff --git a/includes/classes/Feature/Facets/Widget.php b/includes/classes/Feature/Facets/Widget.php index ca53a43ee3..4779c928a0 100644 --- a/includes/classes/Feature/Facets/Widget.php +++ b/includes/classes/Feature/Facets/Widget.php @@ -29,7 +29,11 @@ class Widget extends WP_Widget { * Create widget */ public function __construct() { - $options = array( 'description' => esc_html__( 'Add a facet to an archive or search results page.', 'elasticpress' ) ); + $options = array( + 'description' => esc_html__( 'Add a facet to an archive or search results page.', 'elasticpress' ), + 'show_instance_in_rest' => true, + ); + parent::__construct( 'ep-facet', esc_html__( 'ElasticPress - Facet', 'elasticpress' ), $options ); $this->renderer = new Renderer(); From f7b15a5ef5a4aaf47b142223bc734cf9bc2f8df3 Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Thu, 2 Jun 2022 23:00:51 +1000 Subject: [PATCH 02/16] Hide legacy Facet widget in the block editor by default. --- includes/classes/Feature/Facets/Facets.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/includes/classes/Feature/Facets/Facets.php b/includes/classes/Feature/Facets/Facets.php index 62e3da7dae..a019f60bff 100644 --- a/includes/classes/Feature/Facets/Facets.php +++ b/includes/classes/Feature/Facets/Facets.php @@ -61,6 +61,7 @@ public function __construct() { */ public function setup() { add_action( 'widgets_init', [ $this, 'register_widgets' ] ); + add_filter( 'widget_types_to_hide_from_legacy_widget_block', [ $this, 'hide_legacy_widget' ] ); add_action( 'ep_valid_response', [ $this, 'get_aggs' ], 10, 4 ); add_filter( 'ep_post_formatted_args', [ $this, 'set_agg_filters' ], 10, 3 ); add_action( 'pre_get_posts', [ $this, 'facet_query' ] ); @@ -485,6 +486,20 @@ public function register_widgets() { register_widget( __NAMESPACE__ . '\Widget' ); } + /** + * Hide the legacy widget. + * + * Hides the legacy widget in favor of the Block when the block editor + * is in use and the legacy widget has not been used. + * + * @since 4.3 + */ + function hide_legacy_widget( $widget_types ) { + $widget_types[] = 'ep-facet'; + + return $widget_types; + } + /** * Output feature box long * From bbc0241d287d1a0cb078a1e4b29585af60785b9b Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Thu, 2 Jun 2022 23:37:04 +1000 Subject: [PATCH 03/16] Support transforming Related Posts widget to a Block. --- assets/js/blocks/related-posts/block.js | 2 ++ assets/js/blocks/related-posts/transforms.js | 25 +++++++++++++++++++ .../classes/Feature/RelatedPosts/Widget.php | 6 ++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 assets/js/blocks/related-posts/transforms.js diff --git a/assets/js/blocks/related-posts/block.js b/assets/js/blocks/related-posts/block.js index 3542f90a29..2cc099beee 100644 --- a/assets/js/blocks/related-posts/block.js +++ b/assets/js/blocks/related-posts/block.js @@ -8,6 +8,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies. */ import Edit from './Edit'; +import transforms from './transforms'; registerBlockType('elasticpress/related-posts', { title: __('Related Posts (ElasticPress)', 'elasticpress'), @@ -25,6 +26,7 @@ registerBlockType('elasticpress/related-posts', { default: 5, }, }, + transforms, /** * Handle edit diff --git a/assets/js/blocks/related-posts/transforms.js b/assets/js/blocks/related-posts/transforms.js new file mode 100644 index 0000000000..6b8e05f1df --- /dev/null +++ b/assets/js/blocks/related-posts/transforms.js @@ -0,0 +1,25 @@ +/** + * WordPress dependencies. + */ +import { createBlock } from '@wordpress/blocks'; + +/** + * Facet widget block transforms. + */ +export default { + from: [ + { + type: 'block', + blocks: ['core/legacy-widget'], + isMatch: ({ idBase }) => idBase === 'ep-related-posts', + transform: ({ instance }) => { + const { title, num_posts: number } = instance.raw; + + return [ + createBlock('core/heading', { content: title }), + createBlock('elasticpress/related-posts', { number }), + ]; + }, + }, + ], +}; diff --git a/includes/classes/Feature/RelatedPosts/Widget.php b/includes/classes/Feature/RelatedPosts/Widget.php index 04ee94aa5b..74c1b1823d 100644 --- a/includes/classes/Feature/RelatedPosts/Widget.php +++ b/includes/classes/Feature/RelatedPosts/Widget.php @@ -26,7 +26,11 @@ class Widget extends WP_Widget { * @since 6.4 */ public function __construct() { - $options = array( 'description' => esc_html__( 'Show related posts using ElasticPress. This widget will only appear on single post, page, and custom type pages.', 'elasticpress' ) ); + $options = array( + 'description' => esc_html__( 'Show related posts using ElasticPress. This widget will only appear on single post, page, and custom type pages.', 'elasticpress' ), + 'show_instance_in_rest' => true, + ); + parent::__construct( 'ep-related-posts', esc_html__( 'ElasticPress - Related Posts', 'elasticpress' ), $options ); } From ec77466b9e682cd8507a638a55040c5f5bc88e48 Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Thu, 2 Jun 2022 23:41:57 +1000 Subject: [PATCH 04/16] Hide legacy Related Posts widget in the block editor by default. --- .../classes/Feature/RelatedPosts/RelatedPosts.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/includes/classes/Feature/RelatedPosts/RelatedPosts.php b/includes/classes/Feature/RelatedPosts/RelatedPosts.php index 7045397848..7c9cab33fb 100644 --- a/includes/classes/Feature/RelatedPosts/RelatedPosts.php +++ b/includes/classes/Feature/RelatedPosts/RelatedPosts.php @@ -163,6 +163,7 @@ public function find_related( $post_id, $return = 5 ) { */ public function setup() { add_action( 'widgets_init', [ $this, 'register_widget' ] ); + add_filter( 'widget_types_to_hide_from_legacy_widget_block', [ $this, 'hide_legacy_widget' ] ); add_filter( 'ep_formatted_args', [ $this, 'formatted_args' ], 10, 2 ); add_action( 'init', [ $this, 'register_block' ] ); add_action( 'rest_api_init', [ $this, 'setup_endpoint' ] ); @@ -349,6 +350,20 @@ public function register_widget() { register_widget( __NAMESPACE__ . '\Widget' ); } + /** + * Hide the legacy widget. + * + * Hides the legacy widget in favor of the Block when the block editor + * is in use and the legacy widget has not been used. + * + * @since 4.3 + */ + function hide_legacy_widget( $widget_types ) { + $widget_types[] = 'ep-related-posts'; + + return $widget_types; + } + /** * Output feature box long * From 492c5cbd03342725a8bec72794d4ad123f4629ce Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Thu, 2 Jun 2022 23:56:50 +1000 Subject: [PATCH 05/16] Only insert heading on transform if there is a value. --- assets/js/blocks/facets/transforms.js | 6 +++++- assets/js/blocks/related-posts/transforms.js | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/assets/js/blocks/facets/transforms.js b/assets/js/blocks/facets/transforms.js index 5aa1b2b197..66d5e8b690 100644 --- a/assets/js/blocks/facets/transforms.js +++ b/assets/js/blocks/facets/transforms.js @@ -13,7 +13,11 @@ export default { blocks: ['core/legacy-widget'], isMatch: ({ idBase }) => idBase === 'ep-facet', transform: ({ instance }) => { - const { title, ...attributes } = instance.raw; + const { title = null, ...attributes } = instance.raw; + + if (!title) { + return createBlock('elasticpress/facet', attributes); + } return [ createBlock('core/heading', { content: title }), diff --git a/assets/js/blocks/related-posts/transforms.js b/assets/js/blocks/related-posts/transforms.js index 6b8e05f1df..bb81ea4ec6 100644 --- a/assets/js/blocks/related-posts/transforms.js +++ b/assets/js/blocks/related-posts/transforms.js @@ -13,7 +13,11 @@ export default { blocks: ['core/legacy-widget'], isMatch: ({ idBase }) => idBase === 'ep-related-posts', transform: ({ instance }) => { - const { title, num_posts: number } = instance.raw; + const { title = null, num_posts: number } = instance.raw; + + if (!title) { + return createBlock('elasticpress/related-posts', { number }); + } return [ createBlock('core/heading', { content: title }), From 4b3336b3e94e0d1e289529f0ec046ce2835e77c6 Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Fri, 3 Jun 2022 00:27:54 +1000 Subject: [PATCH 06/16] Fix PHP linting errors. --- includes/classes/Feature/Facets/Facets.php | 8 +++++--- includes/classes/Feature/RelatedPosts/RelatedPosts.php | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/includes/classes/Feature/Facets/Facets.php b/includes/classes/Feature/Facets/Facets.php index a019f60bff..ebe5cd1246 100644 --- a/includes/classes/Feature/Facets/Facets.php +++ b/includes/classes/Feature/Facets/Facets.php @@ -493,11 +493,13 @@ public function register_widgets() { * is in use and the legacy widget has not been used. * * @since 4.3 + * @param array $widgets An array of excluded widget-type IDs. + * @return array array of excluded widget-type IDs to hide. */ - function hide_legacy_widget( $widget_types ) { - $widget_types[] = 'ep-facet'; + public function hide_legacy_widget( $widgets ) { + $widgets[] = 'ep-facet'; - return $widget_types; + return $widgets; } /** diff --git a/includes/classes/Feature/RelatedPosts/RelatedPosts.php b/includes/classes/Feature/RelatedPosts/RelatedPosts.php index 7c9cab33fb..4a6e8c258d 100644 --- a/includes/classes/Feature/RelatedPosts/RelatedPosts.php +++ b/includes/classes/Feature/RelatedPosts/RelatedPosts.php @@ -357,11 +357,13 @@ public function register_widget() { * is in use and the legacy widget has not been used. * * @since 4.3 + * @param array $widgets An array of excluded widget-type IDs. + * @return array array of excluded widget-type IDs to hide. */ - function hide_legacy_widget( $widget_types ) { - $widget_types[] = 'ep-related-posts'; + public function hide_legacy_widget( $widgets ) { + $widgets[] = 'ep-related-posts'; - return $widget_types; + return $widgets; } /** From 855045ad1be63801f36c1586a8f69fba0eb38ee8 Mon Sep 17 00:00:00 2001 From: Jacob Peattie Date: Tue, 21 Jun 2022 20:53:05 +1000 Subject: [PATCH 07/16] Tests WIP. --- assets/js/blocks/facets/edit.js | 41 ++++++- .../components/common/modal.js | 4 +- .../features/related-posts.spec.js | 25 +++-- .../features/related-posts/block.spec.js | 15 +++ .../features/related-posts/widget.spec.js | 100 ++++++++++++++++++ tests/cypress/support/commands.js | 17 +++ 6 files changed, 190 insertions(+), 12 deletions(-) create mode 100644 tests/cypress/integration/features/related-posts/block.spec.js create mode 100644 tests/cypress/integration/features/related-posts/widget.spec.js diff --git a/assets/js/blocks/facets/edit.js b/assets/js/blocks/facets/edit.js index 04d3390418..b988874459 100644 --- a/assets/js/blocks/facets/edit.js +++ b/assets/js/blocks/facets/edit.js @@ -1,14 +1,17 @@ -import { InspectorControls, useBlockProps } from '@wordpress/block-editor'; +import { BlockControls, InspectorControls, useBlockProps } from '@wordpress/block-editor'; import { PanelBody, RadioControl, SelectControl, Spinner, + TextControl, + ToolbarButton, Placeholder, + Popover, } from '@wordpress/components'; import { Fragment, useEffect, useState, useCallback } from '@wordpress/element'; import apiFetch from '@wordpress/api-fetch'; -import { __ } from '@wordpress/i18n'; +import { __, _x } from '@wordpress/i18n'; const FacetBlockEdit = (props) => { const { attributes, setAttributes } = props; @@ -16,7 +19,8 @@ const FacetBlockEdit = (props) => { const [preview, setPreview] = useState(''); const [loading, setLoading] = useState(false); const { facet, orderby, order } = attributes; - + const [isInputDialogVisible, setIsInputDialogVisible] = useState(false); + const [name, setName] = useState(''); const blockProps = useBlockProps(); const load = useCallback(async () => { @@ -42,8 +46,39 @@ const FacetBlockEdit = (props) => { .finally(() => setLoading(false)); }, [facet, orderby, order]); + const InputNameDialog = useCallback( + () => ( + setName(name)} + /> + ), + [name], + ); + return ( + + { + setIsInputDialogVisible(true); + }} + icon="nametag" + > + {isInputDialogVisible && ( + { + setIsInputDialogVisible(false); + }} + > + + + )} + + { {...props} > {isOpen && ( - +