From d235ce61491d2bda4b2c96fa717a799375e2daea Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:29:39 +0200 Subject: [PATCH 001/297] Add plugin dashboard page sample --- build/content-helper/dashboard-page-rtl.css | 1 + build/content-helper/dashboard-page.asset.php | 1 + build/content-helper/dashboard-page.css | 1 + build/content-helper/dashboard-page.js | 1 + src/UI/class-dashboard-page.php | 109 ++++++++++++++++++ .../dashboard-page/dashboard-page.scss | 0 .../dashboard-page/dashboard-page.tsx | 18 +++ webpack.config.js | 4 + wp-parsely.php | 8 +- 9 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 build/content-helper/dashboard-page-rtl.css create mode 100644 build/content-helper/dashboard-page.asset.php create mode 100644 build/content-helper/dashboard-page.css create mode 100644 build/content-helper/dashboard-page.js create mode 100644 src/UI/class-dashboard-page.php create mode 100644 src/content-helper/dashboard-page/dashboard-page.scss create mode 100644 src/content-helper/dashboard-page/dashboard-page.tsx diff --git a/build/content-helper/dashboard-page-rtl.css b/build/content-helper/dashboard-page-rtl.css new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/build/content-helper/dashboard-page-rtl.css @@ -0,0 +1 @@ + diff --git a/build/content-helper/dashboard-page.asset.php b/build/content-helper/dashboard-page.asset.php new file mode 100644 index 0000000000..74d79dc823 --- /dev/null +++ b/build/content-helper/dashboard-page.asset.php @@ -0,0 +1 @@ + array('react', 'wp-dom-ready', 'wp-element'), 'version' => '88e33ab412ec97fad5ab'); diff --git a/build/content-helper/dashboard-page.css b/build/content-helper/dashboard-page.css new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/build/content-helper/dashboard-page.css @@ -0,0 +1 @@ + diff --git a/build/content-helper/dashboard-page.js b/build/content-helper/dashboard-page.js new file mode 100644 index 0000000000..2b3290cc5f --- /dev/null +++ b/build/content-helper/dashboard-page.js @@ -0,0 +1 @@ +!function(){"use strict";var e,r,t,n,o={20:function(e,r,t){var n=t(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),u=Object.prototype.hasOwnProperty,c=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,f={key:!0,ref:!0,__self:!0,__source:!0};function i(e,r,t){var n,a={},i=null,s=null;for(n in void 0!==t&&(i=""+t),void 0!==r.key&&(i=""+r.key),void 0!==r.ref&&(s=r.ref),r)u.call(r,n)&&!f.hasOwnProperty(n)&&(a[n]=r[n]);if(e&&e.defaultProps)for(n in r=e.defaultProps)void 0===a[n]&&(a[n]=r[n]);return{$$typeof:o,type:e,key:i,ref:s,props:a,_owner:c.current}}r.Fragment=a,r.jsx=i,r.jsxs=i},848:function(e,r,t){e.exports=t(20)},609:function(e){e.exports=window.React}},a={};function u(e){var r=a[e];if(void 0!==r)return r.exports;var t=a[e]={exports:{}};return o[e](t,t.exports,u),t.exports}u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,{a:r}),r},u.d=function(e,r){for(var t in r)u.o(r,t)&&!u.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},e=u(848),r=window.wp.domReady,t=u.n(r),n=window.wp.element,t()((function(){(0,n.createRoot)(document.getElementById("parsely-dashboard-page")).render((0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)("h1",{children:"Parse.ly"}),(0,e.jsx)("p",{children:"Welcome to the Parse.ly Dashboard page!"})]}))}))}(); \ No newline at end of file diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php new file mode 100644 index 0000000000..7fd8ceb1ab --- /dev/null +++ b/src/UI/class-dashboard-page.php @@ -0,0 +1,109 @@ +parsely = $parsely; + } + + /** + * Registers the dashboard page. + * + * @since 3.18.0 + */ + public function run(): void { + add_action( 'admin_menu', array( $this, 'add_dashboard_page_to_menu' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_dashboard_page_scripts' ) ); + } + + /** + * Adds the dashboard page to the admin menu. + * + * @since 3.18.0 + */ + public function add_dashboard_page_to_menu(): void { + add_menu_page( + 'Parse.ly Dashboard Page', // Page title. + 'Parse.ly', // Menu title. + 'manage_options', // Capability. + 'parsely-dashboard-page', // Menu slug. + array( $this, 'add_dashboard_page_placeholder' ), // Callback function. + 'dashicons-admin-generic', // Icon URL. + 30 // Position. + ); + } + + /** + * Adds a placeholder for the dashboard page to render into. + * + * @since 3.18.0 + */ + public function add_dashboard_page_placeholder(): void { + echo '
'; + } + + /** + * Enqueues all needed scripts and styles for the dashboard page. + * + * @since 3.18.0 + * + * @param ?string $hook_suffix The current page being loaded. + */ + public function enqueue_dashboard_page_scripts( ?string $hook_suffix ): void { + // Only load the scripts on the dashboard page. + if ( 'toplevel_page_parsely-dashboard-page' !== $hook_suffix ) { + return; + } + + $asset_info = Utils::get_asset_info( 'build/content-helper/dashboard-page.asset.php' ); + $built_assets_url = plugin_dir_url( PARSELY_FILE ) . '/build/content-helper/'; + + wp_enqueue_script( + 'parsely-dashboard-page', + $built_assets_url . 'dashboard-page.js', + $asset_info['dependencies'], + $asset_info['version'], + true + ); + + wp_enqueue_style( + 'parsely-dashboard-page', + $built_assets_url . 'dashboard-page.css', + $asset_info['dependencies'], + $asset_info['version'] + ); + } +} diff --git a/src/content-helper/dashboard-page/dashboard-page.scss b/src/content-helper/dashboard-page/dashboard-page.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/content-helper/dashboard-page/dashboard-page.tsx b/src/content-helper/dashboard-page/dashboard-page.tsx new file mode 100644 index 0000000000..bde2c651f9 --- /dev/null +++ b/src/content-helper/dashboard-page/dashboard-page.tsx @@ -0,0 +1,18 @@ +/** + * WordPress dependencies + */ +import domReady from '@wordpress/dom-ready'; +import { createRoot } from '@wordpress/element'; + +domReady( () => { + const root = createRoot( + document.getElementById( 'parsely-dashboard-page' ) as Element + ); + + root.render( + <> +Welcome to the Parse.ly Dashboard page!
+ > + ); +} ); diff --git a/webpack.config.js b/webpack.config.js index bf2bdd9fd6..be7a1f58a9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,6 +9,10 @@ module.exports = { path.resolve( __dirname, 'src', 'js', 'admin-settings' ), path.resolve( __dirname, 'src', 'css', 'admin-settings.scss' ), ], + 'content-helper/dashboard-page': [ + path.resolve( __dirname, 'src', 'content-helper', 'dashboard-page', 'dashboard-page' ), + path.resolve( __dirname, 'src', 'content-helper', 'dashboard-page', 'dashboard-page.scss' ), + ], 'content-helper/dashboard-widget': [ path.resolve( __dirname, 'src', 'content-helper', 'dashboard-widget', 'dashboard-widget' ), path.resolve( __dirname, 'src', 'content-helper', 'dashboard-widget', 'dashboard-widget.scss' ), diff --git a/wp-parsely.php b/wp-parsely.php index 08beefe75c..21505046d1 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -28,16 +28,15 @@ use Parsely\Content_Helper\Dashboard_Widget; use Parsely\Content_Helper\Editor_Sidebar; -use Parsely\Content_Helper\Excerpt_Suggestions; use Parsely\Content_Helper\Post_List_Stats; use Parsely\Endpoints\GraphQL_Metadata; use Parsely\Endpoints\Rest_Metadata; use Parsely\Integrations\Amp; use Parsely\Integrations\Google_Web_Stories; use Parsely\Integrations\Integrations; -use Parsely\REST_API\REST_API_Controller; use Parsely\UI\Admin_Bar; use Parsely\UI\Admin_Warning; +use Parsely\UI\Dashboard_Page; use Parsely\UI\Metadata_Renderer; use Parsely\UI\Network_Admin_Sites_List; use Parsely\UI\Plugins_Actions; @@ -105,9 +104,14 @@ function parsely_admin_init_register(): void { * Network Admin Sites List table. */ function parsely_wp_admin_early_register(): void { + // Plugin settings page. $GLOBALS['parsely_settings_page'] = new Settings_Page( $GLOBALS['parsely'] ); $GLOBALS['parsely_settings_page']->run(); + // Plugin dashboard page. + $GLOBALS['parsely_dashboard_page'] = new Dashboard_Page( $GLOBALS['parsely'] ); + $GLOBALS['parsely_dashboard_page']->run(); + $network_admin_sites_list = new Network_Admin_Sites_List( $GLOBALS['parsely'] ); $network_admin_sites_list->run(); From 44f69db92642d1aa3108492b259ba40b7af451a0 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 17:54:10 +0200 Subject: [PATCH 002/297] Add dashboard menu item icon --- src/UI/class-dashboard-page.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php index 7fd8ceb1ab..ea94cde5c3 100644 --- a/src/UI/class-dashboard-page.php +++ b/src/UI/class-dashboard-page.php @@ -55,14 +55,18 @@ public function run(): void { * @since 3.18.0 */ public function add_dashboard_page_to_menu(): void { + // Base64-encoded version of leaf-icon.tsx with size of 20 and fill of #1d2327. + // . + $icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCA2MCA2NSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMWQyMzI3IiBkPSJNMjMuNzIsNTEuNTNjMC0uMTgsMC0uMzQtLjA2LS41MmExMy4xMSwxMy4xMSwwLDAsMC0yLjEtNS41M0ExNC43NCwxNC43NCwwLDAsMCwxOS4xMiw0M2MtLjI3LS4yMS0uNS0uMTEtLjUxLjIybC0uMjQsMy40MmMwLC4zMy0uMzguMzUtLjQ5LDBsLTEuNS00LjhhMS40LDEuNCwwLDAsMC0uNzctLjc4LDIzLjkxLDIzLjkxLDAsMCwwLTMuMS0uODRjLTEuMzgtLjI0LTMuMzktLjM5LTMuMzktLjM5LS4zNCwwLS40NS4yMS0uMjUuNDlsMi4wNiwzLjc2Yy4yLjI3LDAsLjU0LS4yOS4zM2wtNC41MS0zLjZhMy42OCwzLjY4LDAsMCwwLTIuODYtLjQ4Yy0xLC4xNi0yLjQ0LjQ2LTIuNDQuNDZhLjY4LjY4LDAsMCwwLS4zOS4yNS43My43MywwLDAsMC0uMTQuNDVTLjQxLDQzLC41NCw0NGEzLjYzLDMuNjMsMCwwLDAsMS4yNSwyLjYyTDYuNDgsNTBjLjI4LjIuMDkuNDktLjIzLjM3bC00LjE4LS45NGMtLjMyLS4xMi0uNSwwLS40LjM3LDAsMCwuNjksMS44OSwxLjMxLDMuMTZhMjQsMjQsMCwwLDAsMS42NiwyLjc0LDEuMzQsMS4zNCwwLDAsMCwxLC41Mmw1LC4xM2MuMzMsMCwuNDEuMzguMS40OEw3LjUxLDU4Yy0uMzEuMS0uMzQuMzUtLjA3LjU1YTE0LjI5LDE0LjI5LDAsMCwwLDMuMDUsMS42NiwxMy4wOSwxMy4wOSwwLDAsMCw1LjkuNSwyNS4xMywyNS4xMywwLDAsMCw0LjM0LTEsOS41NSw5LjU1LDAsMCwxLS4wOC0xLjIsOS4zMiw5LjMyLDAsMCwxLDMuMDctNi45MSI+PC9wYXRoPjxwYXRoIGZpbGw9IiMxZDIzMjciIGQ9Ik01OS43LDQxLjUzYS43My43MywwLDAsMC0uMTQtLjQ1LjY4LjY4LDAsMCwwLS4zOS0uMjVzLTEuNDMtLjMtMi40NC0uNDZhMy42NCwzLjY0LDAsMCwwLTIuODYuNDhsLTQuNTEsMy42Yy0uMjYuMjEtLjQ5LS4wNi0uMjktLjMzbDIuMDYtMy43NmMuMi0uMjguMDktLjQ5LS4yNS0uNDksMCwwLTIsLjE1LTMuMzkuMzlhMjMuOTEsMjMuOTEsMCwwLDAtMy4xLjg0LDEuNCwxLjQsMCwwLDAtLjc3Ljc4bC0xLjUsNC44Yy0uMTEuMzItLjQ4LjMtLjQ5LDBsLS4yNC0zLjQyYzAtLjMzLS4yNC0uNDMtLjUxLS4yMmExNC43NCwxNC43NCwwLDAsMC0yLjQ0LDIuNDdBMTMuMTEsMTMuMTEsMCwwLDAsMzYuMzQsNTFjMCwuMTgsMCwuMzQtLjA2LjUyYTkuMjYsOS4yNiwwLDAsMSwzLDguMSwyNC4xLDI0LjEsMCwwLDAsNC4zNCwxLDEzLjA5LDEzLjA5LDAsMCwwLDUuOS0uNSwxNC4yOSwxNC4yOSwwLDAsMCwzLjA1LTEuNjZjLjI3LS4yLjI0LS40NS0uMDctLjU1bC0zLjIyLTEuMTdjLS4zMS0uMS0uMjMtLjQ3LjEtLjQ4bDUtLjEzYTEuMzgsMS4zOCwwLDAsMCwxLS41MkEyNC42LDI0LjYsMCwwLDAsNTcsNTIuOTJjLjYxLTEuMjcsMS4zMS0zLjE2LDEuMzEtMy4xNi4xLS4zMy0uMDgtLjQ5LS40LS4zN2wtNC4xOC45NGMtLjMyLjEyLS41MS0uMTctLjIzLS4zN2w0LjY5LTMuMzRBMy42MywzLjYzLDAsMCwwLDU5LjQ2LDQ0Yy4xMy0xLC4yNC0yLjQ3LjI0LTIuNDciPjwvcGF0aD48cGF0aCBmaWxsPSIjMWQyMzI3IiBkPSJNNDYuNSwyNS42MWMwLS41My0uMzUtLjcyLS44LS40M2wtNC44NiwyLjY2Yy0uNDUuMjgtLjU2LS4yNy0uMjMtLjY5bDQuNjYtNi4yM2EyLDIsMCwwLDAsLjI4LTEuNjgsMzYuNTEsMzYuNTEsMCwwLDAtMi4xOS00Ljg5LDM0LDM0LDAsMCwwLTIuODEtMy45NGMtLjMzLS40MS0uNzQtLjM1LS45MS4xNmwtMi4yOCw1LjY4Yy0uMTYuNS0uNi40OC0uNTktLjA1bC4yOC04LjkzYTIuNTQsMi41NCwwLDAsMC0uNjYtMS42NFMzNSw0LjI3LDMzLjg4LDMuMjcsMzAuNzguNjksMzAuNzguNjlhMS4yOSwxLjI5LDAsMCwwLTEuNTQsMHMtMS44OCwxLjQ5LTMuMTIsMi41OS0yLjQ4LDIuMzUtMi40OCwyLjM1QTIuNSwyLjUsMCwwLDAsMjMsNy4yN2wuMjcsOC45M2MwLC41My0uNDEuNTUtLjU4LjA1bC0yLjI5LTUuNjljLS4xNy0uNS0uNTctLjU2LS45MS0uMTRhMzUuNzcsMzUuNzcsMCwwLDAtMyw0LjIsMzUuNTUsMzUuNTUsMCwwLDAtMiw0LjYyLDIsMiwwLDAsMCwuMjcsMS42N2w0LjY3LDYuMjRjLjMzLjQyLjIzLDEtLjIyLjY5bC00Ljg3LTIuNjZjLS40NS0uMjktLjgyLS4xLS44Mi40M2ExOC42LDE4LjYsMCwwLDAsLjgzLDUuMDcsMjAuMTYsMjAuMTYsMCwwLDAsNS4zNyw3Ljc3YzMuMTksMyw1LjkzLDcuOCw3LjQ1LDExLjA4QTkuNiw5LjYsMCwwLDEsMzAsNDkuMDlhOS4zMSw5LjMxLDAsMCwxLDIuODYuNDVjMS41Mi0zLjI4LDQuMjYtOC4xMSw3LjQ0LTExLjA5YTIwLjQ2LDIwLjQ2LDAsMCwwLDUuMDktNywxOSwxOSwwLDAsMCwxLjExLTUuODIiPjwvcGF0aD48cGF0aCBmaWxsPSIjMWQyMzI3IiBkPSJNMzYuMTIsNTguNDRBNi4xMiw2LjEyLDAsMSwxLDMwLDUyLjMyYTYuMTEsNi4xMSwwLDAsMSw2LjEyLDYuMTIiPjwvcGF0aD48L3N2Zz4='; + add_menu_page( - 'Parse.ly Dashboard Page', // Page title. - 'Parse.ly', // Menu title. - 'manage_options', // Capability. - 'parsely-dashboard-page', // Menu slug. - array( $this, 'add_dashboard_page_placeholder' ), // Callback function. - 'dashicons-admin-generic', // Icon URL. - 30 // Position. + 'Parse.ly Dashboard Page', + 'Parse.ly', + 'manage_options', + 'parsely-dashboard-page', + array( $this, 'add_dashboard_page_placeholder' ), + $icon, + 30 ); } From 0fdddd44c2b967a206c8ae92f25aeb997f6a9125 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:01:09 +0200 Subject: [PATCH 003/297] Use Parsely::CAPABILITY for dashboard menu item --- src/UI/class-dashboard-page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php index ea94cde5c3..288fbdb976 100644 --- a/src/UI/class-dashboard-page.php +++ b/src/UI/class-dashboard-page.php @@ -62,7 +62,7 @@ public function add_dashboard_page_to_menu(): void { add_menu_page( 'Parse.ly Dashboard Page', 'Parse.ly', - 'manage_options', + Parsely::CAPABILITY, 'parsely-dashboard-page', array( $this, 'add_dashboard_page_placeholder' ), $icon, From 6fa135e02a2dd6095f7a0c51094795d2a8765dcb Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:07:00 +0200 Subject: [PATCH 004/297] Ignore PHPCS capability warning --- src/UI/class-dashboard-page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php index 288fbdb976..b5f82e42f1 100644 --- a/src/UI/class-dashboard-page.php +++ b/src/UI/class-dashboard-page.php @@ -62,7 +62,7 @@ public function add_dashboard_page_to_menu(): void { add_menu_page( 'Parse.ly Dashboard Page', 'Parse.ly', - Parsely::CAPABILITY, + Parsely::CAPABILITY, // phpcs:ignore WordPress.WP.Capabilities.Undetermined 'parsely-dashboard-page', array( $this, 'add_dashboard_page_placeholder' ), $icon, From 2bd14b6f1bd35fa2c41baaccb49b3a9302d6a0d3 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:12:32 +0200 Subject: [PATCH 005/297] Dashboard CSS: Import common resources --- src/content-helper/dashboard-page/dashboard-page.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content-helper/dashboard-page/dashboard-page.scss b/src/content-helper/dashboard-page/dashboard-page.scss index e69de29bb2..c50ca3804f 100644 --- a/src/content-helper/dashboard-page/dashboard-page.scss +++ b/src/content-helper/dashboard-page/dashboard-page.scss @@ -0,0 +1,2 @@ +@import "../common/css/variables"; +@import "../common/css/functions"; From 4d6fbdabd28230422a44c86960fed29c91d72d76 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:14:42 +0200 Subject: [PATCH 006/297] Dashboard_Page: Remove $parsely until we need it --- src/UI/class-dashboard-page.php | 18 ------------------ wp-parsely.php | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php index b5f82e42f1..405f418f5e 100644 --- a/src/UI/class-dashboard-page.php +++ b/src/UI/class-dashboard-page.php @@ -21,24 +21,6 @@ * @since 3.18.0 */ final class Dashboard_Page { - /** - * Instance of Parsely class. - * - * @var Parsely - */ - private $parsely; - - /** - * Constructor. - * - * @since 3.18.0 - * - * @param Parsely $parsely Instance of Parsely class. - */ - public function __construct( Parsely $parsely ) { - $this->parsely = $parsely; - } - /** * Registers the dashboard page. * diff --git a/wp-parsely.php b/wp-parsely.php index 21505046d1..c7a800c3ab 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -109,7 +109,7 @@ function parsely_wp_admin_early_register(): void { $GLOBALS['parsely_settings_page']->run(); // Plugin dashboard page. - $GLOBALS['parsely_dashboard_page'] = new Dashboard_Page( $GLOBALS['parsely'] ); + $GLOBALS['parsely_dashboard_page'] = new Dashboard_Page(); $GLOBALS['parsely_dashboard_page']->run(); $network_admin_sites_list = new Network_Admin_Sites_List( $GLOBALS['parsely'] ); From a6f1b073f1220ac74783e85e8d383af1b3b70259 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:23:17 +0200 Subject: [PATCH 007/297] Rebuild assets --- build/content-helper/dashboard-page-rtl.css | 2 +- build/content-helper/dashboard-page.asset.php | 2 +- build/content-helper/dashboard-page.css | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/content-helper/dashboard-page-rtl.css b/build/content-helper/dashboard-page-rtl.css index 8b13789179..4b3f1772ea 100644 --- a/build/content-helper/dashboard-page-rtl.css +++ b/build/content-helper/dashboard-page-rtl.css @@ -1 +1 @@ - +#wp-parsely-dashboard-widget,.components-button[aria-controls="wp-parsely-block-editor-sidebar:wp-parsely-content-helper"],.editor-post-excerpt,.settings_page_parsely,.wp-parsely-block-overlay,.wp-parsely-content-helper,.wp-parsely-excerpt-generator,.wp-parsely-panel,.wp-parsely-popover,.wp-parsely-preview-editor,.wp-parsely-smart-linking-close-dialog,.wp-parsely-smart-linking-review-modal,.wp-parsely-suggested-title-modal{--base-font:"source-sans-pro",arial,sans-serif;--numeric-font:"ff-din-round-web",sans-serif;--parsely-green-components:107,42%,46%;--parsely-green:hsl(var(--parsely-green-components));--parsely-green-10:#c7ecb1;--parsely-green-65:#2a691b;--gray-200:#f7f8f9;--gray-300:#edeeef;--gray-400:#d7dbdf;--gray-500:#959da5;--gray-600:#586069;--gray-700:#444d56;--gray-900:#24292e;--blue-500:#44a8e5;--blue-550:#2596db;--green-500:#7bc01b;--green-900:#3d6307;--ref-direct:205,13%,52%;--ref-internal:161,91%,41%;--ref-social:210,72%,41%;--ref-search:42,100%,50%;--ref-other:3,76%,58%;--base-text:var(--gray-900);--base-text-2:var(--gray-600);--base-3:var(--gray-400);--border:var(--gray-400);--data:var(--green-500);--control:var(--blue-500);--grid-unit-5:0.25rem;--grid-unit-10:0.5rem;--grid-unit-15:0.75rem;--grid-unit-20:1rem;--grid-unit-25:1.25rem;--grid-unit-30:1.5rem;--grid-unit-40:2rem;--font-size--smaller:0.688rem;--font-size--small:0.75rem;--font-size--medium:0.875rem;--font-size--large:1rem;--font-size--extra-large:1.2rem;--black:#000;--sidebar-black:#1e1e1e;--sidebar-white:#f0f0f0} diff --git a/build/content-helper/dashboard-page.asset.php b/build/content-helper/dashboard-page.asset.php index 74d79dc823..111f7f443a 100644 --- a/build/content-helper/dashboard-page.asset.php +++ b/build/content-helper/dashboard-page.asset.php @@ -1 +1 @@ - array('react', 'wp-dom-ready', 'wp-element'), 'version' => '88e33ab412ec97fad5ab'); + array('react', 'wp-dom-ready', 'wp-element'), 'version' => '12fe4372400030ba8741'); diff --git a/build/content-helper/dashboard-page.css b/build/content-helper/dashboard-page.css index 8b13789179..4b3f1772ea 100644 --- a/build/content-helper/dashboard-page.css +++ b/build/content-helper/dashboard-page.css @@ -1 +1 @@ - +#wp-parsely-dashboard-widget,.components-button[aria-controls="wp-parsely-block-editor-sidebar:wp-parsely-content-helper"],.editor-post-excerpt,.settings_page_parsely,.wp-parsely-block-overlay,.wp-parsely-content-helper,.wp-parsely-excerpt-generator,.wp-parsely-panel,.wp-parsely-popover,.wp-parsely-preview-editor,.wp-parsely-smart-linking-close-dialog,.wp-parsely-smart-linking-review-modal,.wp-parsely-suggested-title-modal{--base-font:"source-sans-pro",arial,sans-serif;--numeric-font:"ff-din-round-web",sans-serif;--parsely-green-components:107,42%,46%;--parsely-green:hsl(var(--parsely-green-components));--parsely-green-10:#c7ecb1;--parsely-green-65:#2a691b;--gray-200:#f7f8f9;--gray-300:#edeeef;--gray-400:#d7dbdf;--gray-500:#959da5;--gray-600:#586069;--gray-700:#444d56;--gray-900:#24292e;--blue-500:#44a8e5;--blue-550:#2596db;--green-500:#7bc01b;--green-900:#3d6307;--ref-direct:205,13%,52%;--ref-internal:161,91%,41%;--ref-social:210,72%,41%;--ref-search:42,100%,50%;--ref-other:3,76%,58%;--base-text:var(--gray-900);--base-text-2:var(--gray-600);--base-3:var(--gray-400);--border:var(--gray-400);--data:var(--green-500);--control:var(--blue-500);--grid-unit-5:0.25rem;--grid-unit-10:0.5rem;--grid-unit-15:0.75rem;--grid-unit-20:1rem;--grid-unit-25:1.25rem;--grid-unit-30:1.5rem;--grid-unit-40:2rem;--font-size--smaller:0.688rem;--font-size--small:0.75rem;--font-size--medium:0.875rem;--font-size--large:1rem;--font-size--extra-large:1.2rem;--black:#000;--sidebar-black:#1e1e1e;--sidebar-white:#f0f0f0} From 212bc1709ca0dc5aba146eb57ad4253f615eb892 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:59:23 +0200 Subject: [PATCH 008/297] Add Traffic Boost permissions infrastructure --- build/admin-settings.asset.php | 2 +- build/admin-settings.js | 2 +- src/UI/class-dashboard-page.php | 32 +++++++++++++++++++++++ src/UI/class-settings-page.php | 18 +++++++++++++ src/class-parsely.php | 5 ++++ src/class-permissions.php | 5 ++++ src/js/admin-settings.ts | 3 ++- tests/Integration/PermissionsTest.php | 1 + tests/Integration/UI/SettingsPageTest.php | 1 + wp-parsely.php | 2 +- 10 files changed, 67 insertions(+), 4 deletions(-) diff --git a/build/admin-settings.asset.php b/build/admin-settings.asset.php index a0dab1c530..3cd200c5ee 100644 --- a/build/admin-settings.asset.php +++ b/build/admin-settings.asset.php @@ -1 +1 @@ - array(), 'version' => '3f06d1e94aa796c8627c'); + array(), 'version' => '6f809310fd8f52110266'); diff --git a/build/admin-settings.js b/build/admin-settings.js index 9922fcdbee..88785066a6 100644 --- a/build/admin-settings.js +++ b/build/admin-settings.js @@ -1 +1 @@ -!function(){"use strict";!function(){function e(){var e,t,n=""!==location.hash?location.hash.substring(1):"basic-section";null===(e=document.querySelectorAll(".nav-tab"))||void 0===e||e.forEach((function(e){e.classList.contains(n+"-tab")?e.classList.add("nav-tab-active"):e.classList.remove("nav-tab-active")})),null===(t=document.querySelectorAll(".tab-content"))||void 0===t||t.forEach((function(e){e.classList.contains(n)?e.setAttribute("style","display: initial"):e.setAttribute("style","display: none")}));var i=document.querySelector('form[name="parsely"]');i&&(i.removeAttribute("hidden"),i.setAttribute("action","options.php#".concat(n)))}function t(e){var t=e.target.dataset.option,n=window.wp.media({multiple:!1,library:{type:"image"}});n.on("select",(function(){var e=n.state().get("selection").first().toJSON().url,i="#media-single-image-"+t+" input.file-path",o=document.querySelector(i);o&&(o.value=e)})),n.open()}document.addEventListener("DOMContentLoaded",(function(){var n;!function(){var e=document.querySelector("input#content_helper_ai_features_enabled"),t=document.querySelectorAll("input#content_helper_smart_linking_enabled, input#content_helper_title_suggestions_enabled, input#content_helper_excerpt_suggestions_enabled"),n=document.querySelectorAll("div.content-helper-section fieldset");function i(){e&&(e.checked?n.forEach((function(e){c(e,!1),t.forEach((function(e){o(e)}))})):(n.forEach((function(t){t.querySelector("#".concat(e.id))||c(t)})),document.querySelectorAll("label.prevent-disable").forEach((function(e){a(e,!1)}))))}function o(e){var t,n,i=null===(n=null===(t=e.closest("fieldset"))||void 0===t?void 0:t.nextSibling)||void 0===n?void 0:n.nextSibling;e.checked?c([e,i],!1):(c(i),a(e.parentElement))}function a(e,t){void 0===t&&(t=!0),t?e.classList.add("prevent-disable"):e.classList.remove("prevent-disable")}function c(e,t){void 0===t&&(t=!0),Array.isArray(e)||(e=[e]),e.forEach((function(e){t?e.setAttribute("disabled","disabled"):e.removeAttribute("disabled")}))}(function(){var e;null===(e=document.querySelector('.wp-admin form[name="parsely"]'))||void 0===e||e.addEventListener("submit",(function(){var e=".wp-admin .content-helper-section fieldset";document.querySelectorAll("".concat(e,"[disabled]")).forEach((function(t){var n,i;null===(i=null===(n=t.parentElement)||void 0===n?void 0:n.parentElement)||void 0===i||i.classList.add("disabled-before-posting"),t.querySelectorAll("".concat(e,' label input[type="checkbox"]')).forEach((function(e){e.classList.add("disabled")})),t.removeAttribute("disabled")}))}))})(),i(),null==e||e.addEventListener("change",(function(){i()})),t.forEach((function(e){e.addEventListener("change",(function(){o(e)}))}))}(),e(),window.addEventListener("hashchange",e),null===(n=document.querySelector(".media-single-image button.browse"))||void 0===n||n.addEventListener("click",t)}))}()}(); \ No newline at end of file +!function(){"use strict";!function(){function e(){var e,t,n=""!==location.hash?location.hash.substring(1):"basic-section";null===(e=document.querySelectorAll(".nav-tab"))||void 0===e||e.forEach((function(e){e.classList.contains(n+"-tab")?e.classList.add("nav-tab-active"):e.classList.remove("nav-tab-active")})),null===(t=document.querySelectorAll(".tab-content"))||void 0===t||t.forEach((function(e){e.classList.contains(n)?e.setAttribute("style","display: initial"):e.setAttribute("style","display: none")}));var i=document.querySelector('form[name="parsely"]');i&&(i.removeAttribute("hidden"),i.setAttribute("action","options.php#".concat(n)))}function t(e){var t=e.target.dataset.option,n=window.wp.media({multiple:!1,library:{type:"image"}});n.on("select",(function(){var e=n.state().get("selection").first().toJSON().url,i="#media-single-image-"+t+" input.file-path",o=document.querySelector(i);o&&(o.value=e)})),n.open()}document.addEventListener("DOMContentLoaded",(function(){var n;!function(){var e=document.querySelector("input#content_helper_ai_features_enabled"),t=document.querySelectorAll("input#content_helper_smart_linking_enabled, input#content_helper_title_suggestions_enabled, input#content_helper_excerpt_suggestions_enabled, input#content_helper_traffic_boost_enabled"),n=document.querySelectorAll("div.content-helper-section fieldset");function i(){e&&(e.checked?n.forEach((function(e){c(e,!1),t.forEach((function(e){o(e)}))})):(n.forEach((function(t){t.querySelector("#".concat(e.id))||c(t)})),document.querySelectorAll("label.prevent-disable").forEach((function(e){a(e,!1)}))))}function o(e){var t,n,i=null===(n=null===(t=e.closest("fieldset"))||void 0===t?void 0:t.nextSibling)||void 0===n?void 0:n.nextSibling;e.checked?c([e,i],!1):(c(i),a(e.parentElement))}function a(e,t){void 0===t&&(t=!0),t?e.classList.add("prevent-disable"):e.classList.remove("prevent-disable")}function c(e,t){void 0===t&&(t=!0),Array.isArray(e)||(e=[e]),e.forEach((function(e){t?e.setAttribute("disabled","disabled"):e.removeAttribute("disabled")}))}(function(){var e;null===(e=document.querySelector('.wp-admin form[name="parsely"]'))||void 0===e||e.addEventListener("submit",(function(){var e=".wp-admin .content-helper-section fieldset";document.querySelectorAll("".concat(e,"[disabled]")).forEach((function(t){var n,i;null===(i=null===(n=t.parentElement)||void 0===n?void 0:n.parentElement)||void 0===i||i.classList.add("disabled-before-posting"),t.querySelectorAll("".concat(e,' label input[type="checkbox"]')).forEach((function(e){e.classList.add("disabled")})),t.removeAttribute("disabled")}))}))})(),i(),null==e||e.addEventListener("change",(function(){i()})),t.forEach((function(e){e.addEventListener("change",(function(){o(e)}))}))}(),e(),window.addEventListener("hashchange",e),null===(n=document.querySelector(".media-single-image button.browse"))||void 0===n||n.addEventListener("click",t)}))}()}(); \ No newline at end of file diff --git a/src/UI/class-dashboard-page.php b/src/UI/class-dashboard-page.php index 405f418f5e..ef97e9b063 100644 --- a/src/UI/class-dashboard-page.php +++ b/src/UI/class-dashboard-page.php @@ -11,6 +11,7 @@ namespace Parsely\UI; use Parsely\Parsely; +use Parsely\Permissions; use Parsely\Utils\Utils; use const Parsely\PARSELY_FILE; @@ -21,6 +22,24 @@ * @since 3.18.0 */ final class Dashboard_Page { + /** + * Instance of Parsely class. + * + * @var Parsely + */ + private $parsely; + + /** + * Constructor. + * + * @since 3.18.0 + * + * @param Parsely $parsely Instance of Parsely class. + */ + public function __construct( Parsely $parsely ) { + $this->parsely = $parsely; + } + /** * Registers the dashboard page. * @@ -59,6 +78,19 @@ public function add_dashboard_page_to_menu(): void { */ public function add_dashboard_page_placeholder(): void { echo ''; + + // TODO: The codeblock below is for demonstration purposes only and + // will be removed in the future. + if ( + Permissions::current_user_can_use_pch_feature( + 'traffic_boost', + $this->parsely->get_options()['content_helper'] + ) + ) { + echo 'Traffic Boost is enabled.'; + } else { + echo 'Traffic Boost is disabled.'; + } } /** diff --git a/src/UI/class-settings-page.php b/src/UI/class-settings-page.php index 766568de19..90dade36ab 100644 --- a/src/UI/class-settings-page.php +++ b/src/UI/class-settings-page.php @@ -72,6 +72,7 @@ * smart_linking?: Parsely_Settings_Options_Content_Helper_Feature, * title_suggestions?: Parsely_Settings_Options_Content_Helper_Feature, * excerpt_suggestions?: Parsely_Settings_Options_Content_Helper_Feature, + * traffic_boost?: Parsely_Settings_Options_Content_Helper_Feature, * } * * @phpstan-type Parsely_Settings_Options_Content_Helper_Feature array{ @@ -118,6 +119,7 @@ final class Settings_Page { 'smart_linking', 'title_suggestions', 'excerpt_suggestions', + 'traffic_boost', ); /** @@ -506,6 +508,22 @@ private function initialize_content_helper_section(): void { $section_key, $field_args ); + + // Traffic Boost. + $field_id = 'content_helper[traffic_boost]'; + $field_args = array( + 'option_key' => $field_id, + 'label_for' => $field_id, + 'legend' => __( 'Traffic Boost', 'wp-parsely' ), + ); + add_settings_field( + $field_id, + __( 'Traffic Boost', 'wp-parsely' ), + array( $this, 'print_content_helper_ai_feature_section' ), + Parsely::MENU_SLUG, + $section_key, + $field_args + ); } /** diff --git a/src/class-parsely.php b/src/class-parsely.php index f3eecee647..b883044d4d 100644 --- a/src/class-parsely.php +++ b/src/class-parsely.php @@ -53,6 +53,7 @@ * smart_linking: Parsely_Options_Content_Helper_Feature, * title_suggestions: Parsely_Options_Content_Helper_Feature, * excerpt_suggestions: Parsely_Options_Content_Helper_Feature, + * traffic_boost: Parsely_Options_Content_Helper_Feature, * } * * @phpstan-type Parsely_Options_Content_Helper_Feature array{ @@ -128,6 +129,10 @@ class Parsely { 'enabled' => true, 'allowed_user_roles' => array( 'administrator' ), ), + 'traffic_boost' => array( + 'enabled' => true, + 'allowed_user_roles' => array( 'administrator' ), + ), ), 'track_authenticated_users' => false, 'lowercase_tags' => true, diff --git a/src/class-permissions.php b/src/class-permissions.php index 01f1f9a203..e82053967f 100644 --- a/src/class-permissions.php +++ b/src/class-permissions.php @@ -162,6 +162,7 @@ public static function get_pch_permissions_json( $pch_options ): string { 'SmartLinking' => 'smart_linking', 'TitleSuggestions' => 'title_suggestions', 'ExcerptSuggestions' => 'excerpt_suggestions', + 'TrafficBoost' => 'traffic_boost', ); foreach ( $features as $key => $value ) { @@ -205,6 +206,10 @@ public static function build_pch_permissions_settings_array( 'enabled' => $enabled, 'allowed_user_roles' => $allowed_user_roles, ), + 'traffic_boost' => array( + 'enabled' => $enabled, + 'allowed_user_roles' => $allowed_user_roles, + ), ); } } diff --git a/src/js/admin-settings.ts b/src/js/admin-settings.ts index 3415a1adf7..eb154543fe 100644 --- a/src/js/admin-settings.ts +++ b/src/js/admin-settings.ts @@ -69,7 +69,8 @@ function addContentHelperTabEventHandlers(): void { const featureCheckboxes = document.querySelectorAllWelcome to the Parse.ly Dashboard page!
- > +Welcome to the main Parse.ly dashboard page.
+ > + ); +}; diff --git a/src/content-helper/dashboard-page/pages/index.tsx b/src/content-helper/dashboard-page/pages/index.tsx new file mode 100644 index 0000000000..e210f311f1 --- /dev/null +++ b/src/content-helper/dashboard-page/pages/index.tsx @@ -0,0 +1,3 @@ +export { DashboardPage } from './dashboard/page-component'; +export { TrafficBoosterPage } from './traffic-booster/page-component'; +export { SettingsPage } from './settings/page-component'; diff --git a/src/content-helper/dashboard-page/pages/settings/page-component.tsx b/src/content-helper/dashboard-page/pages/settings/page-component.tsx new file mode 100644 index 0000000000..925ec087ab --- /dev/null +++ b/src/content-helper/dashboard-page/pages/settings/page-component.tsx @@ -0,0 +1,13 @@ +/** + * Settings page component. + * + * @since 3.18.0 + */ +export const SettingsPage = () => { + return ( + <> +This is a page for settings.
+ > + ); +}; diff --git a/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx b/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx new file mode 100644 index 0000000000..f4481ab5f7 --- /dev/null +++ b/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx @@ -0,0 +1,13 @@ +/** + * Traffic Booster page component. + * + * @since 3.18.0 + */ +export const TrafficBoosterPage = () => { + return ( + <> +This is where the amazing Traffic Booster implementation will live.
+ > + ); +}; From 7fc23ee300e4d73a02f139c75592a32478d6bae0 Mon Sep 17 00:00:00 2001 From: Henrique MoutaThis is where the amazing Traffic Boost implementation will live.
+ > + ); +}; diff --git a/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx b/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx deleted file mode 100644 index f4481ab5f7..0000000000 --- a/src/content-helper/dashboard-page/pages/traffic-booster/page-component.tsx +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Traffic Booster page component. - * - * @since 3.18.0 - */ -export const TrafficBoosterPage = () => { - return ( - <> -This is where the amazing Traffic Booster implementation will live.
- > - ); -}; From ca71b0e3f1ae7c6999bb4bbe04952488090096ec Mon Sep 17 00:00:00 2001 From: Henrique MoutaWelcome to the main Parse.ly dashboard page.
+This is the dashboard page
+Welcome to the main Parse.ly dashboard page.
+This is the dashboard page
+".concat(this.message,"
").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return''.concat((0,x.__)("Hint:","wp-parsely")," ").concat(e,"
")},t.prototype.createErrorSnackbar=function(){/".concat(this.message,"
").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return''.concat((0,x.__)("Hint:","wp-parsely")," ").concat(e,"
")},t.prototype.createErrorSnackbar=function(){/Welcome to the main Parse.ly dashboard page.
- > +Welcome to the Parse.ly Dashboard page!
+Content Helper Permissions: { JSON.stringify( getContentHelperPermissions() ) }
+Traffic Boost Settings: { JSON.stringify( getSettingsFromJson( window.wpParselyContentHelperSettings ) ) }
+ > +This is the dashboard page
-This is a page for settings.
- > +This is a page for settings.
+This is where the amazing Traffic Boost implementation will live.
- > +This is where the amazing Traffic Boost implementation will live.
+".concat(this.message,"
").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return''.concat((0,Se.__)("Hint:","wp-parsely")," ").concat(e,"
")},r.prototype.createErrorSnackbar=function(){/| { __( 'POST', 'wp-parsely' ) } | +{ __( 'BOOST PERFORMANCE', 'wp-parsely' ) } | +|
|---|---|---|
|
+ |
+ 35% | +
+ { __( 'Boost Traffic', 'wp-parsely' ) }
+ |
+
This is the dashboard page
++ { __( + 'Here’s what you’ve published lately. Let’s see if we can improve its performance!', + 'wp-parsely' + ) } +
+".concat(this.message,"
").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return''.concat((0,je.__)("Hint:","wp-parsely")," ").concat(e,"
")},r.prototype.createErrorSnackbar=function(){/- { __( - 'Here’s what you’ve published lately. Let’s see if we can improve its performance!', - 'wp-parsely' - ) } -
-+ { __( + 'Here’s what you’ve published lately. Let’s see if we can improve its performance!', + 'wp-parsely' + ) } +
+".concat(this.message,"
").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return''.concat((0,je.__)("Hint:","wp-parsely")," ").concat(e,"
")},r.prototype.createErrorSnackbar=function(){/".concat(this.message,"
").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return''.concat((0,je.__)("Hint:","wp-parsely")," ").concat(e,"
")},r.prototype.createErrorSnackbar=function(){/".concat(this.message,"
").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return''.concat((0,je.__)("Hint:","wp-parsely")," ").concat(e,"
")},r.prototype.createErrorSnackbar=function(){/