-
Notifications
You must be signed in to change notification settings - Fork 884
Premium Analytics: add React Query Devtools dev-only widget #50002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
retrofox
wants to merge
6
commits into
trunk
Choose a base branch
from
update/react-query-devtools-widget
base: trunk
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+228
−39
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1f164d3
add filterable widget availability layer
retrofox 01df296
add React Query Devtools dev-only widget
retrofox f8db9f1
fix Phan errors in widget availability test
retrofox 8c19a75
tighten widget + availability docblocks
retrofox 3b11b65
fix react-query-devtools widget i18n and deps
retrofox b5b9d68
drop redundant presentation in locations widget
retrofox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
projects/packages/premium-analytics/changelog/add-react-query-devtools-widget
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: minor | ||
| Type: added | ||
|
|
||
| Dashboard: add a React Query Devtools widget, gated to non-production environments through a new `jetpack_premium_analytics_widget_types` filter for scoping widget types server-side. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
projects/packages/premium-analytics/src/widget-availability.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <?php | ||
| /** | ||
| * Widget type availability: a filterable view over the registry. | ||
| * | ||
| * The registry (widget-types.php) holds every widget from the build manifest, | ||
| * unfiltered. This adds the policy layer: the | ||
| * `jetpack_premium_analytics_widget_types` filter, resolved by | ||
| * get_available_widget_types(). The REST list and the page import map both read | ||
| * through it, so dropping a type there hides it from the client entirely. | ||
| * | ||
| * Ships one policy: the developer-only React Query Devtools widget is gated to | ||
| * non-production. Hook the filter to scope types by capability, flag, site, etc. | ||
| * | ||
| * @package automattic/jetpack-premium-analytics | ||
| */ | ||
|
|
||
| namespace Automattic\Jetpack\PremiumAnalytics; | ||
|
|
||
| /** | ||
| * Filter over the available widget types map (`$name => Widget_Type`). | ||
| */ | ||
| const WIDGET_TYPES_FILTER = 'jetpack_premium_analytics_widget_types'; | ||
|
|
||
| /** | ||
| * Returns the widget types available for the current request. | ||
| * | ||
| * Every registered widget type, run through WIDGET_TYPES_FILTER. Use this, not | ||
| * get_registered_widget_types(), anywhere widget types reach the client, so the | ||
| * same policy covers the REST list and the import map. | ||
| * | ||
| * @return Widget_Type[] Map of `$name => Widget_Type`. | ||
| */ | ||
| function get_available_widget_types() { | ||
| /** | ||
| * Filters the widget types available to the dashboard this request. | ||
| * | ||
| * Removing an entry drops it from the `/jetpack/v4/widget-modules` REST list | ||
| * and the page import map, so it cannot be rendered or added. | ||
| * | ||
| * @param Widget_Type[] $widget_types Map of `$name => Widget_Type`. | ||
| */ | ||
| return apply_filters( WIDGET_TYPES_FILTER, get_registered_widget_types() ); | ||
| } | ||
|
|
||
| /** | ||
| * Hides developer-only widget types in production. | ||
| * | ||
| * Keyed off wp_get_environment_type(), which defaults to `production`: a site | ||
| * opts in by declaring `WP_ENVIRONMENT_TYPE` as `local`, `development`, or | ||
| * `staging`. | ||
| * | ||
| * @param Widget_Type[] $widget_types Map of `$name => Widget_Type`. | ||
| * @return Widget_Type[] The map minus developer-only types in production. | ||
| */ | ||
| function filter_widget_types_by_environment( $widget_types ) { | ||
| if ( 'production' !== wp_get_environment_type() ) { | ||
| return $widget_types; | ||
| } | ||
|
|
||
| // Types that must never reach a production dashboard. | ||
| $non_production_only = array( 'jpa/react-query-dev-tool' ); | ||
|
|
||
| foreach ( $non_production_only as $widget_type_name ) { | ||
| unset( $widget_types[ $widget_type_name ] ); | ||
| } | ||
|
|
||
| return $widget_types; | ||
| } | ||
|
|
||
| add_filter( WIDGET_TYPES_FILTER, __NAMESPACE__ . '\\filter_widget_types_by_environment' ); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
projects/packages/premium-analytics/tests/php/Widget_Availability_Test.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| <?php | ||
| /** | ||
| * Tests for the widget type availability layer. | ||
| * | ||
| * @package automattic/jetpack-premium-analytics | ||
| */ | ||
|
|
||
| namespace Automattic\Jetpack\PremiumAnalytics; | ||
|
|
||
| use PHPUnit\Framework\Attributes\CoversFunction; | ||
| use WorDBless\BaseTestCase; | ||
|
|
||
| require_once __DIR__ . '/../../src/widget-types.php'; | ||
| require_once __DIR__ . '/../../src/widget-availability.php'; | ||
|
|
||
| /** | ||
| * @covers ::Automattic\Jetpack\PremiumAnalytics\get_available_widget_types | ||
| * @covers ::Automattic\Jetpack\PremiumAnalytics\filter_widget_types_by_environment | ||
| */ | ||
| #[CoversFunction( 'Automattic\Jetpack\PremiumAnalytics\get_available_widget_types' )] | ||
| #[CoversFunction( 'Automattic\Jetpack\PremiumAnalytics\filter_widget_types_by_environment' )] | ||
| class Widget_Availability_Test extends BaseTestCase { | ||
|
|
||
| /** | ||
| * In production, developer-only widget types are dropped while the rest | ||
| * pass through untouched. | ||
| */ | ||
| public function test_filter_removes_dev_only_widget_in_production() { | ||
| // WorDBless reports the environment type as 'production' by default. | ||
| $this->assertSame( 'production', wp_get_environment_type() ); | ||
|
|
||
| $widget_types = array( | ||
| 'jpa/react-query-dev-tool' => new Widget_Type( 'jpa/react-query-dev-tool' ), | ||
| 'jpa/hello-world' => new Widget_Type( 'jpa/hello-world' ), | ||
| ); | ||
|
|
||
| $filtered = filter_widget_types_by_environment( $widget_types ); | ||
|
|
||
| $this->assertArrayNotHasKey( 'jpa/react-query-dev-tool', $filtered, 'Developer-only widgets must be hidden in production.' ); | ||
| $this->assertArrayHasKey( 'jpa/hello-world', $filtered, 'Regular widgets remain available.' ); | ||
| } | ||
|
|
||
| /** | ||
| * Verifies get_available_widget_types() runs the registry through the | ||
| * WIDGET_TYPES_FILTER so any callback can scope the visible set. | ||
| */ | ||
| public function test_get_available_widget_types_applies_filter() { | ||
| $registry = Widget_Type_Registry::get_instance(); | ||
| $registry->register( 'test/sentinel' ); | ||
|
|
||
| $callback = static function ( $widget_types ) { | ||
| unset( $widget_types['test/sentinel'] ); | ||
| return $widget_types; | ||
| }; | ||
| add_filter( WIDGET_TYPES_FILTER, $callback ); | ||
|
|
||
| $available = get_available_widget_types(); | ||
|
|
||
| remove_filter( WIDGET_TYPES_FILTER, $callback ); | ||
| $registry->unregister( 'test/sentinel' ); | ||
|
|
||
| $this->assertArrayNotHasKey( 'test/sentinel', $available, 'A filter callback can remove a widget type from the available set.' ); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
projects/packages/premium-analytics/widgets/react-query-dev-tool/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "name": "@automattic/jetpack-premium-analytics-widget-react-query-dev-tool", | ||
| "version": "0.1.0-alpha", | ||
| "private": true, | ||
| "type": "module", | ||
| "dependencies": { | ||
| "@jetpack-premium-analytics/data": "link:../../packages/data", | ||
| "@tanstack/react-query-devtools": "5.90.2", | ||
| "@wordpress/i18n": "^6.9.0", | ||
| "@wordpress/icons": "^13.0.0", | ||
| "react": "18.3.1" | ||
| } | ||
| } |
31 changes: 31 additions & 0 deletions
31
projects/packages/premium-analytics/widgets/react-query-dev-tool/render.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| /** | ||
| * External dependencies | ||
| */ | ||
| import { queryClient } from '@jetpack-premium-analytics/data'; | ||
| import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'; | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import styles from './style.module.css'; | ||
|
|
||
| /** | ||
| * React Query Devtools as a dashboard widget. | ||
| * | ||
| * Bound to the shared `queryClient` via the explicit `client` prop rather than | ||
| * the React Query context. The panel renders inside this widget's own lazily | ||
| * loaded module, so a context lookup is not guaranteed to resolve to the | ||
| * dashboard's provider; passing the singleton directly always targets the real | ||
| * cache. | ||
| * | ||
| * Server-gated: widget-availability.php drops `jpa/react-query-dev-tool` in | ||
| * production, so this module is never requested there. | ||
| * | ||
| * @return {React.ReactNode} The rendered devtools panel. | ||
| */ | ||
| export default function ReactQueryDevTool(): React.ReactNode { | ||
| return ( | ||
| <div className={ styles.root }> | ||
| <ReactQueryDevtoolsPanel client={ queryClient } style={ { height: '100%' } } /> | ||
| </div> | ||
| ); | ||
| } |
5 changes: 5 additions & 0 deletions
5
projects/packages/premium-analytics/widgets/react-query-dev-tool/style.module.css
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| .root { | ||
| height: 100%; | ||
| min-height: 480px; | ||
| overflow: auto; | ||
| } |
7 changes: 7 additions & 0 deletions
7
projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "name": "jpa/react-query-dev-tool", | ||
| "title": "React Query Devtools", | ||
| "description": "Inspect the dashboard's React Query cache. Available outside production only.", | ||
| "category": "developer", | ||
| "presentation": "full-bleed" | ||
| } |
18 changes: 18 additions & 0 deletions
18
projects/packages/premium-analytics/widgets/react-query-dev-tool/widget.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { bug } from '@wordpress/icons'; | ||
|
|
||
| /** | ||
| * Widget type definition. | ||
| * | ||
| * Developer tool, gated to non-production server-side by the | ||
| * `jetpack_premium_analytics_widget_types` filter (widget-availability.php). | ||
| * This metadata only describes the type for the dashboard's widget picker. | ||
| */ | ||
| export default { | ||
| name: 'jpa/react-query-dev-tool', | ||
| title: __( 'React Query Devtools', 'jetpack-premium-analytics' ), | ||
| icon: bug, | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a hardcoded list. Maybe we can define a
devcategory and filter the list by it.