From 21eaf61a5b9a4b3a46dd494af1a92fadc6e1475a Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Thu, 30 Jan 2025 15:57:30 +0000 Subject: [PATCH 1/3] remove start page modal --- .../src/class-jetpack-mu-wpcom.php | 1 - .../class-starter-page-templates.php | 451 ------------------ ...lass-wp-rest-sideload-image-controller.php | 295 ------------ .../starter-page-templates/index.scss | 34 -- .../features/starter-page-templates/index.tsx | 44 -- .../page-patterns-plugin.tsx | 153 ------ .../features/starter-page-templates/store.ts | 25 - .../src/block-editor-nux.js | 36 +- .../src/welcome-modal/wpcom-nux.js | 11 +- .../src/welcome-tour/tour-launch.jsx | 22 +- 10 files changed, 19 insertions(+), 1053 deletions(-) delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-starter-page-templates.php delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-wp-rest-sideload-image-controller.php delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.scss delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.tsx delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/page-patterns-plugin.tsx delete mode 100644 projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/store.ts diff --git a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php index 131e524de9278..bc1d49faa4ebd 100644 --- a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php +++ b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php @@ -256,7 +256,6 @@ public static function load_etk_features() { require_once __DIR__ . '/features/wpcom-global-styles/index.php'; require_once __DIR__ . '/features/wpcom-legacy-fse/wpcom-legacy-fse.php'; require_once __DIR__ . '/features/wpcom-whats-new/wpcom-whats-new.php'; - require_once __DIR__ . '/features/starter-page-templates/class-starter-page-templates.php'; } } diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-starter-page-templates.php b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-starter-page-templates.php deleted file mode 100644 index 05e41d690923c..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-starter-page-templates.php +++ /dev/null @@ -1,451 +0,0 @@ -get_templates_cache_key() getter. - * - * @var string - */ - public $templates_cache_key = 'starter_page_templates'; - - /** - * Starter_Page_Templates constructor. - */ - private function __construct() { - // We don't want the user to choose a template when copying a post. - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ( isset( $_GET['jetpack-copy'] ) ) { - return; - } - - /** - * Can be used to disable the Starter Page Templates. - * - * @param bool true if Starter Page Templates should be disabled, false otherwise. - */ - if ( apply_filters( 'a8c_disable_starter_page_templates', false ) ) { - return; - } - - // Register post metas for Launchpad newsletter task and template tracking - add_action( 'init', array( $this, 'register_meta_field' ) ); - // Enqueue scripts and pass templates in a global JS variable - add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_assets' ) ); - // Sideload images to add them to the Media Library for Gallery block images to work - add_action( 'rest_api_init', array( $this, 'register_rest_api' ) ); - // Clean caches - add_action( 'delete_attachment', array( $this, 'clear_sideloaded_image_cache' ) ); - add_action( 'switch_theme', array( $this, 'clear_templates_cache' ) ); - // Handle styles for classic themes - add_action( 'block_editor_settings_all', array( $this, 'add_default_editor_styles_for_classic_themes' ), 10, 2 ); - } - - /** - * Gets the cache key for templates array. - * - * @param string $locale The templates locale. - * - * @return string - */ - public function get_templates_cache_key( string $locale ) { - return $this->templates_cache_key . '_' . $locale; - } - - /** - * Creates instance. - * - * @return \Automattic\Jetpack\Jetpack_Mu_Wpcom\Starter_Page_Templates - */ - public static function get_instance() { - if ( null === self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } - - /** - * Register meta field for storing the template identifier. - */ - public function register_meta_field() { - $args = array( - 'type' => 'string', - 'description' => 'Selected template', - 'single' => true, - 'show_in_rest' => true, - 'object_subtype' => 'page', - 'auth_callback' => function () { - return current_user_can( 'edit_posts' ); - }, - ); - register_meta( 'post', '_starter_page_template', $args ); - - $args = array( - 'type' => 'array', - 'description' => 'Selected category', - 'show_in_rest' => array( - 'schema' => array( - 'type' => 'array', - 'items' => array( - 'type' => 'string', - ), - ), - ), - 'single' => true, - 'object_subtype' => 'page', - 'auth_callback' => function () { - return current_user_can( 'edit_pages' ); - }, - 'sanitize_callback' => function ( $meta_value ) { - if ( ! is_array( $meta_value ) ) { - return array(); - } - - if ( ! class_exists( '\Automattic\Jetpack\Jetpack_Mu_Wpcom\Starter_Page_Templates' ) ) { - return array(); - } - - $starter_page_templates = \Automattic\Jetpack\Jetpack_Mu_Wpcom\Starter_Page_Templates::get_instance(); - // We need to pass a locale in here, but we don't actually depend on it, so we use the default site locale to optimise hitting the pattern cache for the site. - $all_page_templates = $starter_page_templates->get_page_templates( $starter_page_templates->get_verticals_locale() ); - $all_categories = array_merge( ...array_map( 'array_keys', wp_list_pluck( $all_page_templates, 'categories' ) ) ); - - $unique_categories = array_unique( $all_categories ); - - // Only permit values that are valid categories. - return array_intersect( $meta_value, $unique_categories ); - }, - ); - register_meta( 'post', '_wpcom_template_layout_category', $args ); - } - - /** - * Register rest api endpoint for side-loading images. - */ - public function register_rest_api() { - require_once __DIR__ . '/class-wp-rest-sideload-image-controller.php'; - - ( new WP_REST_Sideload_Image_Controller() )->register_routes(); - } - - /** - * Pass error message to frontend JavaScript console. - * - * @param string $message Error message. - */ - public function pass_error_to_frontend( $message ) { - wp_register_script( - 'starter-page-templates-error', - false, - array(), - '1.O', - true - ); - wp_add_inline_script( - 'starter-page-templates-error', - sprintf( - 'console.warn(%s);', - wp_json_encode( $message ) - ) - ); - wp_enqueue_script( 'starter-page-templates-error' ); - } - - /** - * Enqueue block editor assets. - */ - public function enqueue_assets() { - if ( ! function_exists( 'get_current_screen' ) ) { - return; - } - - $screen = get_current_screen(); - $user_locale = Common\get_iso_639_locale( get_user_locale() ); - - // Return early if we don't meet conditions to show templates. - if ( 'page' !== $screen->id ) { - return; - } - - // Load templates for this site. - $page_templates = $this->get_page_templates( $this->get_verticals_locale() ); - if ( $user_locale !== $this->get_verticals_locale() ) { - // If the user locale is not the blog locale, we should show labels in the user locale. - $user_page_templates_indexed = array(); - $user_page_templates = $this->get_page_templates( $user_locale ); - foreach ( $user_page_templates as $page_template ) { - if ( ! empty( $page_template['ID'] ) ) { - $user_page_templates_indexed[ $page_template['ID'] ] = $page_template; - } - } - foreach ( $page_templates as $key => $page_template ) { - if ( isset( $user_page_templates_indexed[ $page_template['ID'] ]['categories'] ) ) { - $page_templates[ $key ]['categories'] = $user_page_templates_indexed[ $page_template['ID'] ]['categories']; - } - if ( isset( $user_page_templates_indexed[ $page_template['ID'] ]['description'] ) ) { - $page_templates[ $key ]['description'] = $user_page_templates_indexed[ $page_template['ID'] ]['description']; - } - } - } - - // Hide non-user-facing categories (Pages, Virtual Theme, and wordpress.com/patterns homepage) in modal - $hidden_categories = array( 'page', 'virtual-theme', '_public_library_homepage' ); - foreach ( $page_templates as &$page_template ) { - if ( ! isset( $page_template['categories'] ) ) { - continue; - } - foreach ( $page_template['categories'] as $category ) { - if ( in_array( $category['slug'], $hidden_categories, true ) ) { - unset( $page_template['categories'][ $category['slug'] ] ); - } - } - } - - if ( empty( $page_templates ) ) { - $this->pass_error_to_frontend( __( 'No templates available. Skipped showing modal window with template selection.', 'jetpack-mu-wpcom' ) ); - return; - } - - $handle = jetpack_mu_wpcom_enqueue_assets( 'starter-page-templates', array( 'js', 'css' ) ); - wp_set_script_translations( $handle, 'jetpack-mu-wpcom', Jetpack_Mu_Wpcom::PKG_DIR . 'languages' ); - - $default_templates = array( - array( - 'ID' => null, - 'title' => __( 'Blank', 'jetpack-mu-wpcom' ), - 'name' => 'blank', - ), - array( - 'ID' => null, - 'title' => __( 'Current', 'jetpack-mu-wpcom' ), - 'name' => 'current', - ), - ); - - $registered_page_templates = $this->get_registered_page_templates(); - - /** - * Filters the config before it's passed to the frontend. - * - * @param array $config The config. - */ - $config = apply_filters( - 'fse_starter_page_templates_config', - array( - 'templates' => array_merge( $default_templates, $registered_page_templates, $page_templates ), - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - 'screenAction' => isset( $_GET['new-homepage'] ) ? 'add' : $screen->action, - ) - ); - - $config = wp_json_encode( $config ); - - wp_add_inline_script( - $handle, - "var starterPageTemplatesConfig = $config;", - 'before' - ); - } - - /** - * Get page templates from the patterns API or return cached version if available. - * - * @param string $locale The templates locale. - * - * @return array Containing page templates or nothing if an error occurred. - */ - public function get_page_templates( string $locale ) { - $page_template_data = get_transient( $this->get_templates_cache_key( $locale ) ); - $override_source_site = apply_filters( 'a8c_override_patterns_source_site', false ); - $disable_cache = function_exists( 'is_automattician' ) && is_automattician() || false !== $override_source_site || ( defined( 'WP_DISABLE_PATTERN_CACHE' ) && WP_DISABLE_PATTERN_CACHE ); - - // Load fresh data if is automattician or we don't have any data. - if ( $disable_cache || false === $page_template_data ) { - $request_url = esc_url_raw( - add_query_arg( - array( - 'site' => $override_source_site ?? 'dotcompatterns.wordpress.com', - 'categories' => 'page', - 'post_type' => 'wp_block', - ), - 'https://public-api.wordpress.com/rest/v1/ptk/patterns/' . $locale - ) - ); - - $args = array( 'timeout' => 20 ); - - if ( function_exists( 'wpcom_json_api_get' ) ) { - $response = wpcom_json_api_get( $request_url, $args ); - } else { - $response = wp_remote_get( $request_url, $args ); - } - - if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { - return array(); - } - - $page_template_data = json_decode( wp_remote_retrieve_body( $response ), true ); - - // Only save to cache when is not disabled. - if ( ! $disable_cache ) { - set_transient( $this->get_templates_cache_key( $locale ), $page_template_data, 5 * MINUTE_IN_SECONDS ); - } - - return $page_template_data; - } - - return $page_template_data; - } - - /** - * Deletes cached attachment data when attachment gets deleted. - * - * @param int $id Attachment ID of the attachment to be deleted. - */ - public function clear_sideloaded_image_cache( $id ) { - $url = get_post_meta( $id, '_sideloaded_url', true ); - if ( ! empty( $url ) ) { - delete_transient( 'fse_sideloaded_image_' . hash( 'crc32b', $url ) ); - } - } - - /** - * Deletes cached templates data when theme switches. - */ - public function clear_templates_cache() { - delete_transient( $this->get_templates_cache_key( $this->get_verticals_locale() ) ); - } - - /** - * Gets the locale to be used for fetching the site vertical - */ - public function get_verticals_locale() { - // Make sure to get blog locale, not user locale. - $language = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_locale(); - return Common\get_iso_639_locale( $language ); - } - - /** - * Gets the registered page templates - */ - public function get_registered_page_templates() { - $registered_page_templates = array(); - - if ( class_exists( 'WP_Block_Patterns_Registry' ) ) { - $registered_categories = $this->get_registered_categories(); - foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { - if ( ! array_key_exists( 'blockTypes', $pattern ) ) { - continue; - } - - $post_content_offset = array_search( 'core/post-content', $pattern['blockTypes'], true ); - if ( $post_content_offset !== false ) { - $categories = array(); - foreach ( $pattern['categories'] as $category ) { - $registered_category = $registered_categories[ $category ]; - if ( $registered_category ) { - $categories[ $category ] = array( - 'slug' => $registered_category['name'], - 'title' => $registered_category['label'], - 'description' => $registered_category['description'], - ); - } - } - - $registered_page_templates[] = array( - 'ID' => null, - 'title' => $pattern['title'], - 'description' => $pattern['description'], - 'name' => $pattern['name'], - 'html' => $pattern['content'], - 'categories' => $categories, - ); - } - } - } - - return $registered_page_templates; - } - - /** - * Gets the registered categories. - */ - public function get_registered_categories() { - $registered_categories = array(); - - if ( class_exists( 'WP_Block_Pattern_Categories_Registry' ) ) { - foreach ( \WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered() as $category ) { - $registered_categories[ $category['name'] ] = $category; - } - } - - return $registered_categories; - } - - /** - * Fix for text overlapping on the page patterns preview on classic themes. - * - * @param array $editor_settings Editor settings. - * @param object $editor_context Editor context. - * - * Only for classic themes because the default styles for block themes include a line-height for the body. - * This issue would not exist if the WordPress wp-admin common.css for the body element (line-height: 1.4em) - * does not overwrite the Gutenberg block-library reset.css for .editor-styles-wrapper (line-height: normal). - * - * This fix adds the default editor styles as custom styles in the editor settings. These are used in the - * editor canvas (.editor-styles-wrapper) and pattern previews (BlockPreview). - * Custom styles are safe because they are overwritten by local block styles, global styles, or theme stylesheets. - **/ - public function add_default_editor_styles_for_classic_themes( $editor_settings, $editor_context ) { - $theme = wp_get_theme( get_stylesheet() ); - if ( $theme->is_block_theme() ) { - // Only for classic themes - return $editor_settings; - } - if ( 'core/edit-post' !== $editor_context->name || 'page' !== $editor_context->post->post_type ) { - // Only for page editor - return $editor_settings; - } - if ( ! function_exists( 'gutenberg_dir_path' ) ) { - return $editor_settings; - } - - $default_editor_styles_file = gutenberg_dir_path() . 'build/block-editor/default-editor-styles.css'; - if ( ! file_exists( $default_editor_styles_file ) ) { - return $editor_settings; - } - $default_editor_styles = file_get_contents( $default_editor_styles_file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents - - $editor_settings['styles'][] = array( - 'css' => $default_editor_styles, - ); - - return $editor_settings; - } -} - -// Initialization -\Automattic\Jetpack\Jetpack_Mu_Wpcom\Starter_Page_Templates::get_instance(); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-wp-rest-sideload-image-controller.php b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-wp-rest-sideload-image-controller.php deleted file mode 100644 index ea547348d731b..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/class-wp-rest-sideload-image-controller.php +++ /dev/null @@ -1,295 +0,0 @@ -namespace = 'fse/v1'; - $this->rest_base = 'sideload/image'; - } - - /** - * Register available routes. - */ - public function register_routes() { - register_rest_route( - $this->namespace, - '/' . $this->rest_base, - array( - array( - 'methods' => \WP_REST_Server::CREATABLE, // @phan-suppress-current-line PhanPluginMixedKeyNoKey - 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'show_in_index' => false, - 'args' => $this->get_collection_params(), - ), - 'schema' => array( $this, 'get_item_schema' ), - ) - ); - - register_rest_route( - $this->namespace, - '/' . $this->rest_base . '/batch', - array( - array( - 'methods' => \WP_REST_Server::CREATABLE, - 'callback' => array( $this, 'create_items' ), - 'permission_callback' => array( $this, 'create_item_permissions_check' ), - 'show_in_index' => false, - 'args' => array( - 'resources' => array( - 'description' => 'URL to the image to be side-loaded.', - 'type' => 'array', - 'required' => true, - 'items' => array( - 'type' => 'object', - 'properties' => $this->get_collection_params(), - ), - ), - ), - ), - ) - ); - } - - /** - * Creates a single attachment. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response Response object on success, WP_Error object on failure. - */ - public function create_item( $request ) { - if ( ! empty( $request['post_id'] ) && in_array( get_post_type( $request['post_id'] ), array( 'revision', 'attachment' ), true ) ) { - return new \WP_Error( 'rest_invalid_param', __( 'Invalid parent type.', 'jetpack-mu-wpcom' ), array( 'status' => 400 ) ); - } - - $inserted = false; - $attachment = $this->get_attachment( $request->get_param( 'url' ) ); - if ( ! $attachment ) { - // Include image functions to get access to wp_read_image_metadata(). - require_once ABSPATH . 'wp-admin/includes/file.php'; - require_once ABSPATH . 'wp-admin/includes/image.php'; - require_once ABSPATH . 'wp-admin/includes/media.php'; - - // The post ID on success, WP_Error on failure. - $id = media_sideload_image( - $request->get_param( 'url' ), - $request->get_param( 'post_id' ), - '', - 'id' - ); - - if ( is_wp_error( $id ) ) { - if ( 'db_update_error' === $id->get_error_code() ) { - $id->add_data( array( 'status' => 500 ) ); - } else { - $id->add_data( array( 'status' => 400 ) ); - } - - return rest_ensure_response( $id ); // Return error. - } - - $attachment = get_post( $id ); - - /** - * Fires after a single attachment is created or updated via the REST API. - * - * @param WP_Post $attachment Inserted or updated attachment object. - * @param WP_REST_Request $request The request sent to the API. - * @param bool $creating True when creating an attachment, false when updating. - */ - do_action( 'rest_insert_attachment', $attachment, $request, true ); - - if ( isset( $request['alt_text'] ) ) { - update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) ); - } - - update_post_meta( $id, '_sideloaded_url', $request->get_param( 'url' ) ); - - $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); - - if ( is_wp_error( $fields_update ) ) { - return $fields_update; - } - - $inserted = true; - $request->set_param( 'context', 'edit' ); - - /** - * Fires after a single attachment is completely created or updated via the REST API. - * - * @param WP_Post $attachment Inserted or updated attachment object. - * @param WP_REST_Request $request Request object. - * @param bool $creating True when creating an attachment, false when updating. - */ - do_action( 'rest_after_insert_attachment', $attachment, $request, true ); - } - - $response = $this->prepare_item_for_response( $attachment, $request ); // @phan-suppress-current-line PhanTypeMismatchArgumentNullable - $response = rest_ensure_response( $response ); - $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', 'wp/v2', 'media', $attachment->ID ) ) ); - - if ( $inserted ) { - $response->set_status( 201 ); - } - - return $response; - } - - /** - * Creates a batch of attachments. - * - * @param \WP_REST_Request $request Full details about the request. - * @return \WP_Error|\WP_REST_Response Response object on success, WP_Error object on failure. - */ - public function create_items( $request ) { - $data = array(); - - // Foreach request specified in the requests param, run the endpoint. - foreach ( $request['resources'] as $resource ) { - $request = new \WP_REST_Request( 'POST', $this->get_item_route() ); - - // Add specified request parameters into the request. - foreach ( $resource as $param_name => $param_value ) { - $request->set_param( $param_name, $param_value ); - } - - $response = rest_do_request( $request ); - $data[] = $this->prepare_for_collection( $response ); - } - - return rest_ensure_response( $data ); - } - - /** - * Prepare a response for inserting into a collection of responses. - * - * @param \WP_REST_Response $response Response object. - * @return array|\WP_REST_Response Response data, ready for insertion into collection data. - */ - public function prepare_for_collection( $response ) { - if ( ! ( $response instanceof \WP_REST_Response ) ) { - return $response; - } - - $data = (array) $response->get_data(); - $server = rest_get_server(); - - if ( method_exists( $server, 'get_compact_response_links' ) ) { - $links = call_user_func( array( $server, 'get_compact_response_links' ), $response ); - } else { - $links = call_user_func( array( $server, 'get_response_links' ), $response ); - } - - if ( ! empty( $links ) ) { - $data['_links'] = $links; - } - - return $data; - } - - /** - * Prepares a single attachment output for response. - * - * @param \WP_Post $post Attachment object. - * @param \WP_REST_Request $request Request object. - * @return \WP_REST_Response Response object. - */ - public function prepare_item_for_response( $post, $request ) { - $response = parent::prepare_item_for_response( $post, $request ); - $base = 'wp/v2/media'; - - foreach ( array( 'self', 'collection', 'about' ) as $link ) { - $response->remove_link( $link ); - - } - - $response->add_link( 'self', rest_url( trailingslashit( $base ) . $post->ID ) ); // @phan-suppress-current-line PhanAccessMethodInternal - $response->add_link( 'collection', rest_url( $base ) ); // @phan-suppress-current-line PhanAccessMethodInternal - $response->add_link( 'about', rest_url( 'wp/v2/types/' . $post->post_type ) ); // @phan-suppress-current-line PhanAccessMethodInternal - - return $response; - } - - /** - * Gets the attachment if an image has been sideloaded previously. - * - * @param string $url URL of the image to sideload. - * @return object|bool Attachment object on success, false on failure. - */ - public function get_attachment( $url ) { - $cache_key = 'fse_sideloaded_image_' . hash( 'crc32b', $url ); - $attachment = get_transient( $cache_key ); - - if ( false === $attachment ) { - $attachments = new \WP_Query( - array( - 'no_found_rows' => true, - 'posts_per_page' => 1, - 'post_status' => 'inherit', - 'post_type' => 'attachment', - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - array( - 'key' => '_sideloaded_url', - 'value' => $url, - ), - ), - ) - ); - - if ( $attachments->have_posts() ) { - set_transient( $cache_key, $attachments->post ); - } - } - - return $attachment; - } - - /** - * Returns the endpoints request parameters. - * - * @return array Request parameters. - */ - public function get_collection_params() { - return array( - 'url' => array( - 'description' => 'URL to the image to be side-loaded.', - 'type' => 'string', - 'required' => true, - 'format' => 'uri', - 'sanitize_callback' => function ( $url ) { - return esc_url_raw( strtok( $url, '?' ) ); - }, - ), - 'post_id' => array( - 'description' => 'ID of the post to associate the image with', - 'type' => 'integer', - 'default' => 0, - ), - ); - } - - /** - * Returns the route to sideload a single image. - * - * @return string - */ - public function get_item_route() { - return "/{$this->namespace}/{$this->rest_base}"; - } -} diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.scss b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.scss deleted file mode 100644 index 45002b1f0750e..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.scss +++ /dev/null @@ -1,34 +0,0 @@ -@import "@automattic/page-pattern-modal/src/styles/page-pattern-modal"; - -.sidebar-modal-opener { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - .pattern-selector-item__label { - max-width: 300px; - } -} - -.sidebar-modal-opener__warning-modal { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.sidebar-modal-opener__warning-text { - max-width: 300px; - font-size: 1rem; - /* stylelint-disable-next-line declaration-property-unit-allowed-list */ - line-height: 1.5rem; -} - -.sidebar-modal-opener__warning-options { - float: right; - margin-top: 20px; - - .components-button { - margin-left: 12px; - } -} diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.tsx b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.tsx deleted file mode 100644 index 1f6422e776671..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { initializeTracksWithIdentity, PatternDefinition } from '@automattic/page-pattern-modal'; -import { dispatch } from '@wordpress/data'; -import { registerPlugin } from '@wordpress/plugins'; -import { PagePatternsPlugin } from './page-patterns-plugin'; -import { pageLayoutStore } from './store'; -import './index.scss'; - -declare global { - interface Window { - starterPageTemplatesConfig?: { - templates?: PatternDefinition[]; - screenAction?: string; - tracksUserData?: Parameters< typeof initializeTracksWithIdentity >[ 0 ]; - }; - } -} - -// Load config passed from backend. -const { - templates: patterns = [], - tracksUserData, - screenAction, -} = window.starterPageTemplatesConfig ?? {}; - -if ( tracksUserData ) { - initializeTracksWithIdentity( tracksUserData ); -} - -// Open plugin only if we are creating new page. -if ( screenAction === 'add' ) { - dispatch( pageLayoutStore ).setOpenState( 'OPEN_FROM_ADD_PAGE' ); -} - -// Always register ability to open from document sidebar. -registerPlugin( 'page-patterns', { - render: () => { - return ; - }, - - // `registerPlugin()` types assume `icon` is mandatory however it isn't - // actually required. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - icon: undefined as any, -} ); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/page-patterns-plugin.tsx b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/page-patterns-plugin.tsx deleted file mode 100644 index 3718dfd82cfcd..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/page-patterns-plugin.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { PagePatternModal, PatternDefinition } from '@automattic/page-pattern-modal'; -import { BlockInstance } from '@wordpress/blocks'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { useCallback } from '@wordpress/element'; -import { addFilter, removeFilter } from '@wordpress/hooks'; -import { __ } from '@wordpress/i18n'; -import { pageLayoutStore } from './store'; -import '@wordpress/nux'; - -const INSERTING_HOOK_NAME = 'isInsertingPagePattern'; -const INSERTING_HOOK_NAMESPACE = 'automattic/full-site-editing/inserting-pattern'; - -interface PagePatternsPluginProps { - patterns: PatternDefinition[]; -} -type CoreEditorPlaceholder = { - getBlocks: ( ...args: unknown[] ) => BlockInstance[]; - getEditedPostAttribute: ( ...args: unknown[] ) => unknown; -}; -type CoreEditPostPlaceholder = { - isFeatureActive: ( ...args: unknown[] ) => boolean; -}; -type CoreNuxPlaceholder = { - areTipsEnabled: ( ...args: unknown[] ) => boolean; -}; - -/** - * Recursively finds the Content block if any. - * - * @param blocks - The current blocks - * @return Block found, if any - */ -function findPostContentBlock( blocks: BlockInstance[] ): BlockInstance | null { - for ( const block of blocks ) { - if ( block.name === 'core/post-content' || block.name === 'a8c/post-content' ) { - return block; - } - const result = findPostContentBlock( block.innerBlocks ); - if ( result ) { - return result; - } - } - return null; -} - -/** - * Starter page templates feature plugin - * - * @param props - An object that receives the page patterns - * @return {JSX.Element} The rendered page pattern modal component. - */ -export function PagePatternsPlugin( props: PagePatternsPluginProps ): JSX.Element { - const { setOpenState } = useDispatch( pageLayoutStore ); - const { setUsedPageOrPatternsModal } = useDispatch( 'automattic/wpcom-welcome-guide' ); - const { replaceInnerBlocks } = useDispatch( 'core/block-editor' ); - const { editPost } = useDispatch( 'core/editor' ); - const { toggleFeature } = useDispatch( 'core/edit-post' ); - const { disableTips } = useDispatch( 'core/nux' ); - - const selectProps = useSelect( select => { - const { isOpen, isPatternPicker } = select( pageLayoutStore ); - return { - isOpen: isOpen(), - isWelcomeGuideActive: ( - select( 'core/edit-post' ) as CoreEditPostPlaceholder - ).isFeatureActive( 'welcomeGuide' ) as boolean, - areTipsEnabled: ( select( 'core/nux' ) as CoreNuxPlaceholder ).areTipsEnabled() as boolean, - ...( isPatternPicker() && { - title: __( 'Choose a Pattern', 'jetpack-mu-wpcom' ), - description: __( - 'Pick a pre-defined layout or continue with a blank page', - 'jetpack-mu-wpcom' - ), - } ), - }; - }, [] ); - - const { getMeta, postContentBlock } = useSelect( select => { - const getMetaNew = () => - ( select( 'core/editor' ) as CoreEditorPlaceholder ).getEditedPostAttribute( 'meta' ); - const currentBlocks = ( select( 'core/editor' ) as CoreEditorPlaceholder ).getBlocks(); - return { - getMeta: getMetaNew, - postContentBlock: findPostContentBlock( currentBlocks ), - }; - }, [] ); - - const savePatternChoice = useCallback( - ( name: string, selectedCategory: string | null ) => { - // Save selected pattern slug in meta. - const currentMeta = getMeta() as Record< string, unknown >; - const currentCategory = - ( Array.isArray( currentMeta._wpcom_template_layout_category ) && - currentMeta._wpcom_template_layout_category ) || - []; - editPost( { - meta: { - ...currentMeta, - _starter_page_template: name, - _wpcom_template_layout_category: [ ...currentCategory, selectedCategory ], - }, - } ); - }, - [ editPost, getMeta ] - ); - - const insertPattern = useCallback( - ( title: string | null, blocks: unknown[] ) => { - // Add filter to let the tracking library know we are inserting a template. - addFilter( INSERTING_HOOK_NAME, INSERTING_HOOK_NAMESPACE, () => true ); - - // Set post title. - if ( title ) { - editPost( { title } ); - } - - // Replace blocks. - replaceInnerBlocks( postContentBlock ? postContentBlock.clientId : '', blocks, false ); - - // Remove filter. - removeFilter( INSERTING_HOOK_NAME, INSERTING_HOOK_NAMESPACE ); - }, - [ editPost, postContentBlock, replaceInnerBlocks ] - ); - - const { isWelcomeGuideActive, areTipsEnabled } = selectProps; - - const hideWelcomeGuide = useCallback( () => { - if ( isWelcomeGuideActive ) { - // Gutenberg 7.2.0 or higher. - toggleFeature( 'welcomeGuide' ); - } else if ( areTipsEnabled ) { - // Gutenberg 7.1.0 or lower. - disableTips(); - } - }, [ areTipsEnabled, disableTips, isWelcomeGuideActive, toggleFeature ] ); - - const handleClose = useCallback( () => { - setOpenState( 'CLOSED' ); - setUsedPageOrPatternsModal?.(); - }, [ setOpenState, setUsedPageOrPatternsModal ] ); - - return ( - - ); -} diff --git a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/store.ts b/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/store.ts deleted file mode 100644 index 93bcaf2542eac..0000000000000 --- a/projects/packages/jetpack-mu-wpcom/src/features/starter-page-templates/store.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { register, createReduxStore } from '@wordpress/data'; - -type OpenState = 'CLOSED' | 'OPEN_FROM_ADD_PAGE' | 'OPEN_FOR_BLANK_CANVAS'; - -const reducer = ( state = 'CLOSED', { type, ...action } ) => - 'SET_IS_OPEN' === type ? action.openState : state; - -const actions = { - setOpenState: ( openState: OpenState | false ) => ( { - type: 'SET_IS_OPEN' as const, - openState: openState || 'CLOSED', - } ), -}; - -export const selectors = { - isOpen: ( state: OpenState ): boolean => 'CLOSED' !== state, - isPatternPicker: ( state: OpenState ): boolean => 'OPEN_FOR_BLANK_CANVAS' === state, -}; - -export const pageLayoutStore = createReduxStore( 'automattic/starter-page-layouts', { - reducer, - actions, - selectors, -} ); -register( pageLayoutStore ); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/block-editor-nux.js b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/block-editor-nux.js index 1dd45c58ac09a..aa6a04617d746 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/block-editor-nux.js +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/block-editor-nux.js @@ -16,7 +16,7 @@ import FirstPostPublishedModal from './first-post-published-modal'; import PurchaseNotice from './purchase-notice'; import RecommendedTagsModal from './recommended-tags-modal'; import SellerCelebrationModal from './seller-celebration-modal'; -import { DEFAULT_VARIANT, BLANK_CANVAS_VARIANT } from './store'; +import { DEFAULT_VARIANT } from './store'; import VideoPressCelebrationModal from './video-celebration-modal'; import WpcomNux from './welcome-modal/wpcom-nux'; import LaunchWpcomWelcomeTour from './welcome-tour/tour-launch'; @@ -30,26 +30,18 @@ function WelcomeTour() { getQueryArg( window.location.href, 'showDraftPostModal' ) ); - const { show, isLoaded, variant, isManuallyOpened, isNewPageLayoutModalOpen } = useSelect( - select => { - const welcomeGuideStoreSelect = select( 'automattic/wpcom-welcome-guide' ); - const starterPageLayoutsStoreSelect = select( 'automattic/starter-page-layouts' ); + const { show, isLoaded, variant } = useSelect( select => { + const welcomeGuideStoreSelect = select( 'automattic/wpcom-welcome-guide' ); - return { - show: welcomeGuideStoreSelect.isWelcomeGuideShown(), - isLoaded: welcomeGuideStoreSelect.isWelcomeGuideStatusLoaded(), - variant: welcomeGuideStoreSelect.getWelcomeGuideVariant(), - isManuallyOpened: welcomeGuideStoreSelect.isWelcomeGuideManuallyOpened(), - isNewPageLayoutModalOpen: starterPageLayoutsStoreSelect?.isOpen(), // Handle the case where SPT is not initalized. - }; - }, - [] - ); + return { + show: welcomeGuideStoreSelect.isWelcomeGuideShown(), + isLoaded: welcomeGuideStoreSelect.isWelcomeGuideStatusLoaded(), + variant: welcomeGuideStoreSelect.getWelcomeGuideVariant(), + }; + }, [] ); const siteEditorCanvasMode = useCanvasMode(); - const setOpenState = useDispatch( 'automattic/starter-page-layouts' )?.setOpenState; - const { fetchWelcomeGuideStatus } = useDispatch( 'automattic/wpcom-welcome-guide' ); // On mount check if the WPCOM welcome guide status exists in state (from local storage), otherwise fetch it from the API. @@ -61,7 +53,7 @@ function WelcomeTour() { const filteredShow = applyFilters( 'a8c.WpcomBlockEditorWelcomeTour.show', show ); - if ( ! filteredShow || isNewPageLayoutModalOpen ) { + if ( ! filteredShow ) { return null; } @@ -70,14 +62,6 @@ function WelcomeTour() { return null; } - // Open patterns panel before Welcome Tour if necessary (e.g. when using Blank Canvas theme) - // Do this only when Welcome Tour is not manually opened. - // NOTE: at the moment, 'starter-page-templates' assets are not loaded on /site-editor/ page so 'setOpenState' may be undefined - if ( variant === BLANK_CANVAS_VARIANT && ! isManuallyOpened && setOpenState ) { - setOpenState( 'OPEN_FOR_BLANK_CANVAS' ); - return null; - } - if ( variant === DEFAULT_VARIANT ) { return ( diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-modal/wpcom-nux.js b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-modal/wpcom-nux.js index 828df3697d86a..2a921bbb51b9a 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-modal/wpcom-nux.js +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-modal/wpcom-nux.js @@ -15,11 +15,8 @@ import './style.scss'; * @return {JSX.Element} The WpcomNux component or null. */ function WpcomNux() { - const { show, isNewPageLayoutModalOpen, isManuallyOpened } = useSelect( select => ( { + const { show, isManuallyOpened } = useSelect( select => ( { show: select( 'automattic/wpcom-welcome-guide' ).isWelcomeGuideShown(), - isNewPageLayoutModalOpen: - select( 'automattic/starter-page-layouts' ) && // Handle the case where SPT is not initalized. - select( 'automattic/starter-page-layouts' ).isOpen(), isManuallyOpened: select( 'automattic/wpcom-welcome-guide' ).isWelcomeGuideManuallyOpened(), } ) ); @@ -27,15 +24,15 @@ function WpcomNux() { // Track opening of the welcome guide useEffect( () => { - if ( show && ! isNewPageLayoutModalOpen ) { + if ( show ) { wpcomTrackEvent( 'calypso_editor_wpcom_nux_open', { is_gutenboarding: window.calypsoifyGutenberg?.isGutenboarding, is_manually_opened: isManuallyOpened, } ); } - }, [ isManuallyOpened, isNewPageLayoutModalOpen, show ] ); + }, [ isManuallyOpened, show ] ); - if ( ! show || isNewPageLayoutModalOpen ) { + if ( ! show ) { return null; } diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-tour/tour-launch.jsx b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-tour/tour-launch.jsx index 277353f9864aa..71e04a35018e9 100644 --- a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-tour/tour-launch.jsx +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-block-editor-nux/src/welcome-tour/tour-launch.jsx @@ -20,13 +20,9 @@ import './style-tour.scss'; * @return {JSX.Element|null} The welcome tour component or null. */ function LaunchWpcomWelcomeTour() { - const { show, isNewPageLayoutModalOpen, isManuallyOpened } = useSelect( + const { show, isManuallyOpened } = useSelect( select => ( { show: select( 'automattic/wpcom-welcome-guide' ).isWelcomeGuideShown(), - // Handle the case where the new page pattern modal is initialized and open - isNewPageLayoutModalOpen: - select( 'automattic/starter-page-layouts' ) && - select( 'automattic/starter-page-layouts' ).isOpen(), isManuallyOpened: select( 'automattic/wpcom-welcome-guide' ).isWelcomeGuideManuallyOpened(), } ), [] @@ -47,7 +43,7 @@ function LaunchWpcomWelcomeTour() { if ( isBlogOnboardingFlow ) { return; } - if ( ! show && ! isNewPageLayoutModalOpen ) { + if ( ! show ) { return; } @@ -62,17 +58,9 @@ function LaunchWpcomWelcomeTour() { intent: siteIntent, editor_type: editorType, } ); - }, [ - isNewPageLayoutModalOpen, - isManuallyOpened, - show, - siteIntent, - siteIntentFetched, - editorType, - isBlogOnboardingFlow, - ] ); - - if ( ! show || isNewPageLayoutModalOpen || isBlogOnboardingFlow ) { + }, [ isManuallyOpened, show, siteIntent, siteIntentFetched, editorType, isBlogOnboardingFlow ] ); + + if ( ! show || isBlogOnboardingFlow ) { return null; } From 01a29327cbc5048650177b344a0118f0ed85865f Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 31 Jan 2025 17:56:35 +0000 Subject: [PATCH 2/3] changelog --- .../jetpack-mu-wpcom/changelog/remove-start-page-modal | 4 ++++ .../plugins/mu-wpcom-plugin/changelog/remove-start-page-modal | 4 ++++ projects/plugins/wpcomsh/changelog/remove-start-page-modal | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 projects/packages/jetpack-mu-wpcom/changelog/remove-start-page-modal create mode 100644 projects/plugins/mu-wpcom-plugin/changelog/remove-start-page-modal create mode 100644 projects/plugins/wpcomsh/changelog/remove-start-page-modal diff --git a/projects/packages/jetpack-mu-wpcom/changelog/remove-start-page-modal b/projects/packages/jetpack-mu-wpcom/changelog/remove-start-page-modal new file mode 100644 index 0000000000000..ebecfd8ee319e --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/remove-start-page-modal @@ -0,0 +1,4 @@ +Significance: minor +Type: removed + +Start page pattern modal: Removed start page pattern modal. We will default to core behaviour from now on, which has equivalent functionality. diff --git a/projects/plugins/mu-wpcom-plugin/changelog/remove-start-page-modal b/projects/plugins/mu-wpcom-plugin/changelog/remove-start-page-modal new file mode 100644 index 0000000000000..ebecfd8ee319e --- /dev/null +++ b/projects/plugins/mu-wpcom-plugin/changelog/remove-start-page-modal @@ -0,0 +1,4 @@ +Significance: minor +Type: removed + +Start page pattern modal: Removed start page pattern modal. We will default to core behaviour from now on, which has equivalent functionality. diff --git a/projects/plugins/wpcomsh/changelog/remove-start-page-modal b/projects/plugins/wpcomsh/changelog/remove-start-page-modal new file mode 100644 index 0000000000000..ebecfd8ee319e --- /dev/null +++ b/projects/plugins/wpcomsh/changelog/remove-start-page-modal @@ -0,0 +1,4 @@ +Significance: minor +Type: removed + +Start page pattern modal: Removed start page pattern modal. We will default to core behaviour from now on, which has equivalent functionality. From 7a18a5e0a8331ccb0ac47b12d36bd849c946eb5d Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Fri, 31 Jan 2025 17:57:25 +0000 Subject: [PATCH 3/3] missed web pack config --- projects/packages/jetpack-mu-wpcom/webpack.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/packages/jetpack-mu-wpcom/webpack.config.js b/projects/packages/jetpack-mu-wpcom/webpack.config.js index abc603c4b3bb0..985fb7cbbb7ba 100644 --- a/projects/packages/jetpack-mu-wpcom/webpack.config.js +++ b/projects/packages/jetpack-mu-wpcom/webpack.config.js @@ -56,7 +56,6 @@ module.exports = [ 'wpcom-profile-settings-link-to-wpcom': './src/features/wpcom-profile-settings/profile-settings-link-to-wpcom.ts', 'wpcom-sidebar-notice': './src/features/wpcom-sidebar-notice/wpcom-sidebar-notice.js', - 'starter-page-templates': './src/features/starter-page-templates/index.tsx', 'removed-calypso-screen-notice': './src/features/wpcom-admin-interface/removed-calypso-screen-notice.tsx', 'adminbar-launch-button': './src/features/launch-button/index.js',