Premium Analytics: dashboard on core Gutenberg packages (@next) - #49793
Conversation
Layer the Gutenberg-linked dashboard (WidgetDashboard + local layout/grid hooks + widget registry + default-layout) onto premium-analytics, replacing the placeholder dashboard. Link @wordpress/{widget-dashboard,widget-primitives} to the local Gutenberg trunk worktree (gutenberg-midnight). Trunk's Sync/connect/syncing/REST untouched.
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 🔴 Action required: Please include detailed testing steps, explaining how to test your change, like so: 🔴 Action required: We would recommend that you add a section to the PR description to specify whether this PR includes any changes to data or privacy, like so: Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Backup plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Social plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Videopress plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Mu Wpcom plugin:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Wpcomsh plugin:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. Premium Analytics plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
Merge trunk's connect/syncing redirect guard into route.ts beforeLoad (was dropped when the route was replaced), then register the widgetModule entity.
Switch @wordpress/widget-{dashboard,primitives} from local link: to the npm 'next' dist-tag; drop the local Gutenberg docker mount. Host pieces (registry/endpoints/default-layout) stay.
The dashboard externalizes @wordpress/private-apis; only the Gutenberg plugin ships a private-apis whose opt-in allowlist includes @wordpress/widget-dashboard. Activate the plugin in the env.
Map the local Gutenberg checkout into the env for the private-apis runtime; packages stay on the npm 'next' tag.
| && ! $gutenberg_active | ||
| && version_compare( $GLOBALS['wp_version'] ?? '0', $force_threshold, '<' ); |
There was a problem hiding this comment.
If GB is active, but is an older version without the required package version support, this could break things.
There was a problem hiding this comment.
You could hardcode GB v22.6 check against GUTENBERG_VERSION when the threshold is set to 7.0? Since it's just a safeguard, hardcoding seems fine.
https://developer.wordpress.org/block-editor/contributors/versions-in-wordpress/
There was a problem hiding this comment.
Good catch, agreed.
We'll gate on GUTENBERG_VERSION (≥ 22.6 for the 7.0 threshold) so an older active Gutenberg still gets the superset polyfill instead of being skipped.
track @wordpress/private-apis @next so widget-dashboard opt-in resolves
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Code Coverage SummaryCoverage changed in 2 files.
5 files are newly checked for coverage.
Full summary · PHP report · JS report If appropriate, add one of these labels to override the failing coverage check:
Covered by non-unit tests
|
simplify isset ternary to null coalescing in dashboard-layout; suppress wp-build-generated jpa_get_registered_widget_modules in widget-types
declare jetpack-script-data + @wordpress/route deps; remove blank lines between import groups; complete hook and widget JSDoc
remove proxy-registry tarball: entries so the lockfile matches trunk/CI (npmjs registry omits them)
sync reference + description in the 6 dependent plugins after the polyfill changes
changelog entries for the 6 plugins whose composer.lock referenced wp-build-polyfills
reselect bumped to 5.2.0 via trunk; the 5.1.1 exclude is no longer installed
| @@ -0,0 +1,113 @@ | |||
| <?php | |||
There was a problem hiding this comment.
@retrofox do we need this because the packages we rely on are only front-end files, and this would only be available if we are on the latest GB or WP version?
Or is it expected for each plugin to create their own widget type?
There was a problem hiding this comment.
We have this file and several others because:
-
They establish the foundation of the system's operational infrastructure, which powers the widget system and, in part, the dashboard.
-
They haven't yet been published in Gutenberg/Core, as they are still tied to an experimental feature.
And no, the idea isn't for each plugin to set up its own system. Rather, as a purely temporary measure, we decided to create our own system in Premium Analytics.
We're talking about the most delicate piece of the entire implementation, mainly because it would be embedded within the WordPress core, which is no small matter.
louwie17
left a comment
There was a problem hiding this comment.
Thanks @retrofox & @nerrad for working on this, this tested well! I also checked some of the existing dashboards that rely on the polyfills.
The Premium Analytics dashboard also works great 👍
Code otherwise looks good, the dashboard stuff we can certainly iterate on.
I appreciate the addition of the GB and WP version checks per package 🥇
seed SCRIPT_FILENAME so wp_guess_url avoids an empty-needle warning on PHP < 8
| "@wordpress/widget-dashboard": "next", | ||
| "@wordpress/widget-primitives": "next", |
There was a problem hiding this comment.
Is using "next" rather than an actual version number going to require lockfile updates every time a new "next" is tagged?
There was a problem hiding this comment.
Thanks and good feedback.
Short answer: no. pnpm pins the resolved snapshot (0.1.1-next.v.202606191442.0) in the lockfile, and CI's --frozen-lockfile only compares thenext specifier; it never re-hits the registry.
So a new next does not break CI or need a lockfile update.
The real trade-off is the opposite: the pin only moves on an explicit pnpm update, and any unrelated lockfile regen pulls whatever next points to at that moment, so we can get a surprise bump in a non-related diff.
These two are the experimental dashboard-widgets packages with no stable release yet, so next was the only tag.
We are pinning them to the exact version in Douglas's PR (#49838), the same place we scope the polyfill.
There was a problem hiding this comment.
Short answer: no. pnpm pins the resolved snapshot (
0.1.1-next.v.202606191442.0) in the lockfile, and CI's--frozen-lockfileonly compares thenextspecifier; it never re-hits the registry.
It seems your AI is unaware of the "Lock files are up to date" CI check. It looks like that would indeed start complaining as soon as a new "next" version is released.
We are pinning them to the exact version in Douglas's PR (#49838), the same place we scope the polyfill.
Good!
There was a problem hiding this comment.
Is using "next" rather than an actual version number going to require lockfile updates every time a new "next" is tagged?
It looks like that would indeed start complaining as soon as a new "next" version is released.
Good!
Thanks for answering the question. So setting the dependencies to a fixed tag will avoid this, right?
There was a problem hiding this comment.
Yes, using versions like 0.1.1-next.v.202606191442.0, as in #49838, will be fine.
What?
A customizable widget dashboard in
premium-analytics, built on the core Gutenberg packages from npm@next(@wordpress/widget-dashboard,@wordpress/widget-primitives) — with no Gutenberg plugin requirement at runtime.It also adds the host-side pieces Gutenberg leaves to the consumer: the widget-type registry,
/jetpack/v4/widget-modulesplus itswidgetModulecore-data entity, and the/jetpack/v4/dashboards/{name}/default-layoutbackend.Why?
@wordpress/widget-dashboardreaches private component APIs (the actionsMenu, the command palette) through@wordpress/private-apis, which gates them behind an allowlist of consenting module names.WordPress core ships a private-apis whose allowlist does not cover the newer dashboard packages, so historically only a Gutenberg plugin checkout provided a complete-enough allowlist.
Requiring Gutenberg beside the repo made the dashboard impractical to ship.
How?
wp-build-polyfillsnow provides the runtime@wordpress/private-apisitself.When core's bundled version is incomplete (WP < 7.1) and Gutenberg is not active, the package force-replaces the
wp-private-apisscript handle with a strict superset build whose allowlist covers the dashboard packages (@wordpress/widget-dashboard,@wordpress/ui,@wordpress/admin-ui,@wordpress/dataviews,@wordpress/route, …).The polyfill bundles
@wordpress/private-apisstraight from npm, so its allowlist is exactly the published one. It now tracks the@nextdist-tag (matching the dashboard packages).That is what closes the last gap: the
@nextprivate-apis allowlist includes@wordpress/widget-dashboard, whereas the previously-resolved1.48.1did not. That mismatch threw at bundle init (__dangerousOptInToUnstableAPIsOnlyForCoreModulesrejects an unlisted module) and aborted the SPA before any widget rendered.Net result: the dashboard runs on core packages with no Gutenberg plugin, no docker Gutenberg mount, and no composer/plugin dependency.
Testing
pulls @wordpress/* @next, incl. private-apis @next
Open the Premium Analytics dashboard in wp-admin (
?page=jetpack-premium-analytics). No Gutenberg activation needed; widgets render and the date-range / comparison menus (privateMenu) work.Runtime sanity check (browser console on the dashboard page) — the polyfill's allowlist now accepts the dashboard packages:
Broader wp-build-polyfills regression coverage
Because this PR changes the shared
wp-build-polyfillspackage, also verify that other Jetpack wp-build admin pages still load when their route bundles depend onwp-private-apis,wp-theme,@wordpress/boot, and@wordpress/route.Note
This testing matrix was derived by GPT 5.5 as a result of prompting to investigate the usage of the packages polyfilled by the
wp-build-polyfillspackage and surfacing the relevant user facing UI/UX impacted by the changes. If when testing, you find incorrect/incoherent instructions - update this list.Recommended environment matrix:
wp-private-apisis served by the Jetpack polyfill, and the dashboard packages can opt in without throwing.wp-private-apisis still served by the Jetpack polyfill. Gutenberg 23.4.0 and older do not have the private-apis allowlist entry needed by@wordpress/widget-dashboard.wp-private-apisis trusted and the Jetpack polyfill does not force-replace it. The page still loads without private API allowlist errors.@wordpress/widget-dashboardWordPress/gutenberg#79268 /cbf74db259das the stand-in for this versioned-release case.-alpha( needed as7.1-alphais still seen as below7.1):wp-private-apis; the polyfill does not unnecessarily replace it.The key threshold to verify is
GUTENBERG_PRIVATE_APIS_MIN_VERSION = '23.5.0': test one Gutenberg version below that threshold and one at or above it, because the replacement logic intentionally treats those cases differently. Since there is not yet a Gutenberg 23.5.0 tag, use Gutenberg trunk containing WordPress/gutenberg#79268 /cbf74db259dfor the at-or-above-threshold test.For each environment, open the following wp-build-backed screens and confirm the page renders, route navigation works, and the browser console has no missing script/module errors or
__dangerousOptInToUnstableAPIsOnlyForCoreModulesallowlist errors:wp-admin/admin.php?page=jetpack-premium-analyticswp-admin/admin.php?page=jetpack-forms-responses-wp-adminwp-admin/admin.php?page=jetpack-backupwp-admin/admin.php?page=jetpack-socialwp-admin/admin.php?page=jetpack-newsletterandwp-admin/admin.php?page=jetpack-subscriberswp-admin/admin.php?page=jetpack-videopresswp-admin/admin.php?page=jetpack-seowp-admin/admin.php?page=jetpack-scanRuntime checks from the browser console on at least the Premium Analytics and one non-Premium Analytics wp-build page:
When testing the Gutenberg-version threshold, also confirm the registered script source matches the expected provider:
wp-private-apisshould point atjetpack-wp-build-polyfills.< 23.5.0:wp-private-apisshould still point atjetpack-wp-build-polyfills.>= 23.5.0:wp-private-apisshould remain Gutenberg-provided. Until a 23.5.0 tag exists, verify this with a Gutenberg trunk build containing Widget Dashboard: extract into@wordpress/widget-dashboardWordPress/gutenberg#79268 /cbf74db259d.wp-private-apisshould remain Core-provided.Targeted automated checks:
jetpack test php packages/wp-build-polyfills jetpack build packages/wp-build-polyfills jetpack build packages/premium-analytics jetpack build packages/forms jetpack build packages/backup jetpack build packages/newsletter jetpack build packages/publicize jetpack build packages/scan jetpack build packages/seo jetpack build packages/videopressFollow-ups
CORE_MODULES_USING_PRIVATE_APIS⊇ every opt-in name used by the bundled packages — so a future@nextpackage can't reintroduce the gap.