Skip to content

Premium Analytics: port the Average items per order widget#49505

Merged
adamwoodnz merged 24 commits into
trunkfrom
add/wooa7s-1460-port-woo-widget-average-items-per-order
Jun 24, 2026
Merged

Premium Analytics: port the Average items per order widget#49505
adamwoodnz merged 24 commits into
trunkfrom
add/wooa7s-1460-port-woo-widget-average-items-per-order

Conversation

@nerrad

@nerrad nerrad commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Why?

This ports the WooCommerce Analytics "Average items per order" widget into Premium Analytics, validates it in the dashboard shell through Storybook, and fixes compact dashboard rendering issues found while testing one-column widget layouts.

Proposed changes

  • Add the jpa/average-items-per-order widget metadata, render module, package entry, and changelog entry.
  • Compose the widget from the Premium Analytics data, fields, and widgets-toolkit packages: order report data, range editing, metric value, comparison delta, and comparative line chart.
  • Register Premium Analytics widgets in Storybook and add a dashboard-context story at Packages/Premium Analytics/Widgets/AverageItemsPerOrder / WidgetDashboardWithWidget.
  • Extract a shared dashboard story helper so future widget stories can exercise widgets in the real dashboard shell with adjustable dashboard/widget sizing.
  • Tighten comparative chart legend wrapping so compact one-column dashboard widgets do not clip wrapped comparison labels under WordPress admin typography.
  • Fix dashboard support package metadata/changelog coverage for grid, widget-dashboard, and widget-primitives.
  • Keep widget-local error handling out of this PR; that path is being explored separately in draft PR Premium Analytics: Add dashboard widget error handling #49657.

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

Requires pnpm ^11.5 and Node ^24.15.

  • Build Premium Analytics: pnpm --filter @automattic/jetpack-premium-analytics build.
  • Typecheck the affected packages:
    • pnpm --filter @automattic/jetpack-widget-dashboard typecheck
    • pnpm --filter @automattic/jetpack-widget-primitives typecheck
    • pnpm --filter @automattic/jetpack-premium-analytics typecheck
  • Build Storybook: pnpm --filter @automattic/jetpack-storybook storybook:build.
  • In Storybook, open Packages/Premium Analytics/Widgets/AverageItemsPerOrder / WidgetDashboardWithWidget.
  • Use the story controls for dashboard width, widget width/height, row height, host environment, and comparison mode. Confirm compact one-column dashboard sizes keep the wrapped comparison legend centered and unclipped.
  • On a test site with WooCommerce and the WooCommerce Analytics plugin active, build/sync Premium Analytics, then open Premium Analytics -> Customize -> Add widget -> Average items per order.
  • Confirm the widget mounts, loads the primary and comparison order report requests, and renders the metric value, comparison delta, chart, legend, and hover tooltip.
  • Open widget settings and change the Range field. Confirm the range editor renders and changing the range refetches the report.

@nerrad nerrad self-assigned this Jun 10, 2026
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the add/wooa7s-1460-port-woo-widget-average-items-per-order branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack add/wooa7s-1460-port-woo-widget-average-items-per-order
bin/jetpack-downloader test jetpack-mu-wpcom-plugin add/wooa7s-1460-port-woo-widget-average-items-per-order

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

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 🤖


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!


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.

@jp-launch-control

jp-launch-control Bot commented Jun 10, 2026

Copy link
Copy Markdown

Code Coverage Summary

This PR did not change code coverage!

That could be good or bad, depending on the situation. Everything covered before, and still is? Great! Nothing was covered before? Not so great. 🤷

Full summary · PHP report · JS report

@nerrad nerrad force-pushed the add/wooa7s-1460-port-woo-widget-average-items-per-order branch from d922903 to 74722f2 Compare June 11, 2026 21:40
@nerrad nerrad force-pushed the update/pa-introduce-customize-dashboard branch from 91aa9fb to 909996e Compare June 11, 2026 22:51
@nerrad nerrad force-pushed the add/wooa7s-1460-port-woo-widget-average-items-per-order branch from 74722f2 to 4538b65 Compare June 11, 2026 22:53
@nerrad

nerrad commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up: the reportParams range editor, and where the toolkit pieces should land

Context for reviewers on the one fidelity gap in this PR (no user-editable date range), plus proposed next steps now that widgets-toolkit (#49422) has landed and we can plan its dissolution — it was always a transitional construct for the port.

The problem

The upstream widget declares an editable range attribute with a custom dataviews Edit component:

attributes: [ { id: 'reportParams', label: 'Range', Edit: ReportParamsField } ]

Widget attributes flow into the dashboard's settings drawer, which renders them directly through DataForm with no per-widget form wiring (widget-settings.tsx#L75-L86):

const fields = useMemo< Field< WidgetAttributes >[] >(
	() => ( widgetType?.attributes ?? [] ) as Field< WidgetAttributes >[],
	[ widgetType?.attributes ]
);

…where widgetType.attributes comes straight from the widget's metadata module per the contract (widget-primitives types.ts#L108):

attributes?: Field< Item >[];

So the Edit component must ship inside the widget's metadata module (widget.ts), which useWidgetTypes() imports eagerly for every registered widget at dashboard boot.

That's where it breaks. In @wordpress/build's buildWidget(), the two builds get different plugin sets — render.* gets style handling, widget.* doesn't:

// render.min.js build:
plugins: [
	...createStyleBundlingPlugins( widgetDir ),   // CSS modules → style runtime
	wordpressExternalsPlugin( 'render.min', 'esm', [], true ),
],
// widget.min.js (metadata) build:
plugins: [
	styleRuntimeAliasPlugin(),                    // no sass/css-modules support
	wordpressExternalsPlugin( 'widget.min', 'esm', [], true ),
],

And ReportParamsField's import graph carries .module.scss (date-report-params-field.tsx#L16):

import { DateFiltersPanel } from '@jetpack-premium-analytics/ui';

✘ [ERROR] No loader is configured for ".scss" files the moment widget.ts imports the field. So this PR ships no editable attributes; new instances bake the default last-30-days + comparison range via example.attributes.

Nobody else hits this: premium-analytics is the only consumer of wp-build's widget pipeline, and the ecosystem convention elsewhere avoids the pattern entirely — block.json metadata is pure JSON with edit components living in editor bundles, and wpScript packages keep styles out of the JS graph (separate build-style/ compilation). Our own hello-world widget already follows the safe form, a string-typed control with no component import (hello-world/widget.ts#L14-L20):

attributes: [
	{
		id: 'message',
		label: 'Message',
		type: 'text',
	},
],

Notably, the dashboard host already does exactly what ReportParamsField wants to do — a custom styled DataForm control — but defined in the host bundle, which builds with full style support (layout-model-edit-field/index.tsx#L60):

}: DataFormControlProps< WidgetGridSettings > ): React.ReactNode {

The pattern works; the problem is purely where the component code lives.

Proposed next steps (doubles as the toolkit dissolution plan)

1. Host-level providers; dissolve WidgetRoot. Today every widget instance mounts its own providers (widget-root.tsx#L120-L128):

<AnalyticsQueryClientProvider>
	<GlobalChartsProvider theme={ chartTheme }>
		<WidgetRootContext.Provider value={ contextValue }>

…and the QueryClient is a module-scope singleton per bundle (query-client-provider.tsx#L109), so each widget gets its own cache. Since react/react-dom are externalized to the WP-shared instance in widget bundles (from the generated render.min.asset.php: 'dependencies' => array('react', 'react-dom', …)), context crosses bundle boundaries — the dashboard route can mount the providers once around WidgetDashboard, widgets shrink to a useResolvedReportParams( attributes ) hook + chart composition, and identical report requests dedupe across widgets via the shared cache. Small PR, pays off before widget #2.

2. Declarative metadata; resolve Edit controls by name. Keep widget.ts to strings/icon (block.json philosophy); the attribute declares a control reference (e.g. edit: 'jpa/report-params') and the host registers implementations via a small registry in the widget-primitives contract — the field implementation moves to a bundle built by the route pipeline, which has style support (per the host precedent above). Kills this build issue permanently and the eager-load weight of bundling a date picker into N metadata modules. Needs contract discussion since widget-primitives is headed upstream.

3. Upstream chart compositions to @automattic/charts. ComparativeLineChart, ChartTooltip, empty-state helpers, metric value/delta. Charts' compositions directory is literally waiting (charts/src/compositions/index.ts):

// Compositions directory - prepared for future use
export {};

One decoupling needed first — these components import the analytics-local formatters directly (comparative-line-chart.tsx#L5):

import { formatDate, formatMetricValue } from '@jetpack-premium-analytics/formatters';

Make formatting injectable via props (formatValue/formatDate) so the analytics flavoring stays at the call site.

4. Regardless of the above: file the render/metadata style-plugin asymmetry upstream against @wordpress/build — the next widget-pipeline consumer will trip on it for something lighter than a date picker.

End state: data hooks stay in the data package, charts pieces live in charts, field controls live host-side, and widgets-toolkit deletes itself.

*left by Biff (AI agent) on behalf of Darren

@nerrad nerrad left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides the inline comments, the package-lock.json diff seems to be larger than it should be?

Comment thread projects/packages/premium-analytics/widgets/average-items-per-order/widget.ts Outdated
Comment thread projects/js-packages/grid/tsconfig.json Outdated
@nerrad nerrad force-pushed the add/wooa7s-1460-port-woo-widget-average-items-per-order branch from 9607ed8 to 9461614 Compare June 17, 2026 11:19
@nerrad nerrad force-pushed the update/pa-introduce-customize-dashboard branch from 5bb6dd9 to 7ff7f71 Compare June 17, 2026 11:19
@nerrad nerrad marked this pull request as ready for review June 17, 2026 12:10
@adamwoodnz adamwoodnz force-pushed the add/wooa7s-1460-port-woo-widget-average-items-per-order branch from 32820ab to 11af3a3 Compare June 23, 2026 02:05

@adamwoodnz adamwoodnz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebased this on trunk and tested in storybook. Generally looks good.

Left a comment on the storybook setup.

@nerrad nerrad requested review from adamwoodnz and chihsuan June 23, 2026 17:52
adamwoodnz
adamwoodnz previously approved these changes Jun 24, 2026

@adamwoodnz adamwoodnz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I'll update #49679 based on these stories.

adamwoodnz pushed a commit that referenced this pull request Jun 24, 2026
…cations to AGENTS.md

Add a new ## Widgets section anchored to the widget layout introduced in
#49505 (Average items per order): documents the required
widgets/<name>/{package.json,widget.json,widget.ts,render.tsx,stories/}
folder structure, the WidgetDashboardWithWidget-based story template,
the Packages/Premium Analytics/Widgets/<WidgetName> title path,
registerReportMocks() / autodocs requirements, the
projects/js-packages/storybook/storybook/projects.js registration step,
and widget-specific pitfalls (including avoiding the legacy
packages/widgets-toolkit/src/widgets/* path and the legacy
withWidgetRoot() decorator).

Also restructure the existing ## Overview into a bulleted list with
more detail on each consolidated surface (Odyssey dashboard /
apps/odyssey-stats / email stats, and a link to the private
woocommerce/woocommerce-analytics repo).

Co-authored-by: Jasper Kang <kangzjnet@gmail.com>
chihsuan
chihsuan previously approved these changes Jun 24, 2026

@chihsuan chihsuan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks @nerrad

Comment on lines +3 to +6
min-height: 0;
flex: 1 1 auto;
display: flex;
flex-direction: column;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should replace the regular div with the chart class with a Stack component. It's acting like a part of the component layout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm not sure what the purpose of these styles is. I guess we're trying to force the widget to take the whole height, but I thought that height: 100% should be enough?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, it's needed to stretch its immediate children. Below:

	> div {
		flex: 1 1 auto;
		min-height: 0;
	}

Using this > div class doesn't look good .

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points, I've replaced with Stack, but it looks like here are still some style tweaks needed. This particular component is in the widgets-toolkit package and is one of the ones that should be migrated to @automattic/charts as a part of the composite chart components. So I think this can help inform that eventual migration (and further SCSS edits can happen as a part of that).

@retrofox retrofox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice PR. It works very nicely 💯

I have my reservations, though, about merging it 😅

The implementation mitigates the lack of a proper process for adjusting the chart's visualization based on its size by adding CSS that should be handled by the Chart library.

This is something we should avoid from now, IMO.

I prefer discarding this part, merging the PR without it, and handling the auto-resize in the Chart library, or eventually in a wrapper.

@retrofox

Copy link
Copy Markdown
Contributor

While testing I noticed the widget renders poorly in the Add widget picker preview. wanted to flag it and check whether it's intentionally out of scope for now.

This is fair feedback, and I believe we should handle it upstream. The widget inserter is part of WidgetDashboard's area of responsibility.

@dognose24

Copy link
Copy Markdown
Contributor

This is fair feedback, and I believe we should handle it upstream. The widget inserter is part of WidgetDashboard's area of responsibility.

It should be due to the overly general CSS selector .dataviews-view-picker-grid .dataviews-view-picker-grid__media img, which I remember encountering before.

截圖 2026-06-24 下午3 33 41

louwie17 added a commit that referenced this pull request Jun 24, 2026
…tions

Address PR #49568 review feedback:

* Collapse the widget into render.tsx (matching the canonical hello-world
  reference). Remove top-posts-widget.tsx, index.ts and types.ts; rename the
  presentational TopPostsWidget component to TopPostsLeaderboard and keep it
  internal. A widget is the block-level abstraction (widget.json + widget.ts +
  render.tsx), so render.tsx is the component itself, like a block's edit.js.
* Stop exporting TopPostsAttributes / TopPostRow (used only here).
* Rename top-posts-widget.module.css -> top-posts.module.css.
* i18n: wrap widget.ts title and attribute labels in __().
* Replace the native anchor with the @wordpress/ui Link component
  (openInNewTab + unstyled variant to preserve the leaderboard row styling).
* Defer the Storybook story to the #49505 follow-up; drop its stale changelog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9fmCCXRxMgNf9whczP122
@nerrad nerrad dismissed stale reviews from chihsuan and adamwoodnz via 428a124 June 24, 2026 17:01
@nerrad

nerrad commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

The implementation mitigates the lack of a proper process for adjusting the chart's visualization based on its size by adding CSS that should be handled by the Chart library.

@retrofox I agree with this generally, however it's important to note that currently this component is not in the @automattic/charts library - changes here can inform what is missing for implementation when migrating these composite components there. I left a comment about this in reply to your inline review comment (along with implementing Stack like you suggested 😄).

@retrofox retrofox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Darren, for addressing all feedback 💯 I think it can be shipped and follow-ups can continue.

adamwoodnz added a commit that referenced this pull request Jun 24, 2026
From nerrad's review (#4524224327):
- Note widgets-toolkit primitives are built on @automattic/charts, and flag
  the toolkit as an interim layer whose module paths are provisional.
- Drop the explicit #49505 link from the legacy note so it can't go stale.
- Trim the widget pitfalls to the two non-obvious legacy traps; the rest just
  restated the REQUIRED folder-structure / story rules above.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2vY2GxKEJurnaod7phrFo
@adamwoodnz adamwoodnz merged commit e329317 into trunk Jun 24, 2026
101 checks passed
@adamwoodnz adamwoodnz deleted the add/wooa7s-1460-port-woo-widget-average-items-per-order branch June 24, 2026 22:51
adamwoodnz added a commit that referenced this pull request Jun 24, 2026
…d Overview clarifications (#49679)

* Premium Analytics: Add widget Storybook guidance and Overview clarifications to AGENTS.md

Add a new ## Widgets section anchored to the widget layout introduced in
#49505 (Average items per order): documents the required
widgets/<name>/{package.json,widget.json,widget.ts,render.tsx,stories/}
folder structure, the WidgetDashboardWithWidget-based story template,
the Packages/Premium Analytics/Widgets/<WidgetName> title path,
registerReportMocks() / autodocs requirements, the
projects/js-packages/storybook/storybook/projects.js registration step,
and widget-specific pitfalls (including avoiding the legacy
packages/widgets-toolkit/src/widgets/* path and the legacy
withWidgetRoot() decorator).

Also restructure the existing ## Overview into a bulleted list with
more detail on each consolidated surface (Odyssey dashboard /
apps/odyssey-stats / email stats, and a link to the private
woocommerce/woocommerce-analytics repo).

Co-authored-by: Jasper Kang <kangzjnet@gmail.com>

* Premium Analytics: make widget story guidance a self-contained template

Rework the AGENTS.md story guidance so an agent can build all three required
stories from the doc alone, without copying a specific widget's story file
(which can drift). Inline snippets for each story — Default and WithComparison
close-ups plus the WidgetDashboardWithWidget harness story — share one setup
block. Reconcile the surrounding requirements: the dashboard story proves the
in-product render while the close-ups use a plain canvas decorator, and the
legacy note no longer points at an example widget as the thing to copy.

Also corrects the WidgetRenderProps import, which pointed at a non-existent
@automattic/jetpack-widget-primitives package; the real type comes from
@wordpress/widget-primitives.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2vY2GxKEJurnaod7phrFo

* Premium Analytics: address review feedback on widget AGENTS.md

From nerrad's review (#4524224327):
- Note widgets-toolkit primitives are built on @automattic/charts, and flag
  the toolkit as an interim layer whose module paths are provisional.
- Drop the explicit #49505 link from the legacy note so it can't go stale.
- Trim the widget pitfalls to the two non-obvious legacy traps; the rest just
  restated the REQUIRED folder-structure / story rules above.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2vY2GxKEJurnaod7phrFo

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Jasper Kang <kangzjnet@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added [Status] UI Changes Add this to PRs that change the UI so documentation can be updated. and removed [Status] In Progress labels Jun 25, 2026
louwie17 added a commit that referenced this pull request Jun 25, 2026
…tions

Address PR #49568 review feedback:

* Collapse the widget into render.tsx (matching the canonical hello-world
  reference). Remove top-posts-widget.tsx, index.ts and types.ts; rename the
  presentational TopPostsWidget component to TopPostsLeaderboard and keep it
  internal. A widget is the block-level abstraction (widget.json + widget.ts +
  render.tsx), so render.tsx is the component itself, like a block's edit.js.
* Stop exporting TopPostsAttributes / TopPostRow (used only here).
* Rename top-posts-widget.module.css -> top-posts.module.css.
* i18n: wrap widget.ts title and attribute labels in __().
* Replace the native anchor with the @wordpress/ui Link component
  (openInNewTab + unstyled variant to preserve the leaderboard row styling).
* Defer the Storybook story to the #49505 follow-up; drop its stale changelog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9fmCCXRxMgNf9whczP122
louwie17 added a commit that referenced this pull request Jun 26, 2026
* Premium Analytics: wire Top posts & pages widget to the designated stats hooks

Rebased onto trunk. The presentational TopPostsWidget, the stats proxy data
layer, and the designated useStatsTopPosts traffic hook have all since landed in
trunk, so this is reduced to the widget glue that connects them:

* widgets/top-posts/{widget.json,widget.ts,package.json} — register the
  `jpa/stats-top-posts` framed widget with range/num attributes.
* widgets/top-posts/render.tsx — fetch via the designated `useStatsTopPosts`
  hook, resolve the range preset to an absolute window, adapt the normalized
  report items to the `TopPostRow[]` the presentational widget expects, and
  filter by post type client-side.
* widgets/top-posts/__tests__/top-posts.test.tsx — render/empty/post-type tests
  driven through the stats proxy (apiFetch mocked).
* packages/data: re-export `computeDateRangeFromPreset` from the package root.
* tests: stub CSS imports so widget render tests can pull in widgets-toolkit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017bmLMW4mTLBLuLtMaNvUca

* Premium Analytics: link widgets-toolkit, icons & init internal packages

The top-posts widget imports @jetpack-premium-analytics/widgets-toolkit,
which transitively imports @jetpack-premium-analytics/icons. These bare
specifiers resolve via Node module resolution to the link: symlinks in
node_modules, but the package only declared 7 of the 10 internal packages.
Add the missing link: entries (icons, init, widgets-toolkit) so the widget
builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nz61RCPHjp2tot41TskF12

* Premium Analytics: fix ESLint issues in top-posts widget

Re-apply lint fixes after rebase:
- Wrap the type-guard arrow in render.tsx's toTopPostRows (prettier/prettier).
- Order the @jetpack-premium-analytics/widgets-toolkit import before the
  @WordPress imports in top-posts-widget.tsx (import/order).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNH44m2sKKhtnU4yNmvFqj

* Premium Analytics: align Top posts widget structure with block conventions

Address PR #49568 review feedback:

* Collapse the widget into render.tsx (matching the canonical hello-world
  reference). Remove top-posts-widget.tsx, index.ts and types.ts; rename the
  presentational TopPostsWidget component to TopPostsLeaderboard and keep it
  internal. A widget is the block-level abstraction (widget.json + widget.ts +
  render.tsx), so render.tsx is the component itself, like a block's edit.js.
* Stop exporting TopPostsAttributes / TopPostRow (used only here).
* Rename top-posts-widget.module.css -> top-posts.module.css.
* i18n: wrap widget.ts title and attribute labels in __().
* Replace the native anchor with the @wordpress/ui Link component
  (openInNewTab + unstyled variant to preserve the leaderboard row styling).
* Defer the Storybook story to the #49505 follow-up; drop its stale changelog.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9fmCCXRxMgNf9whczP122

* Premium Analytics: type Top posts render export as WidgetRenderProps

Use the host-provided `WidgetRenderProps<TopPostsAttributes>` from
@wordpress/widget-primitives for the widget's render entry point instead of a
hand-rolled props type — this matches the contract the widget dashboard invokes
render modules with (`ComponentType<WidgetRenderProps<unknown>>`). Add the
package to the widget's dependencies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9fmCCXRxMgNf9whczP122

* Premium Analytics: restore Top posts Storybook story; inline link label

* Re-add the prop-driven Top posts & pages story (stories/top-posts.stories.tsx)
  targeting the now-exported presentational `TopPostsLeaderboard`. Storybook has
  no analytics backend, so the data-connected entry point would only show empty
  chrome — driving the presentational layer with fixture rows is the only way to
  show populated, comparison, and long-label states.
* Export `TopPostsLeaderboard` and the `TopPostRow` type for the story.
* Inline the small `TopPostLabel` component into `buildLeaderboardData`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9fmCCXRxMgNf9whczP122

* Premium Analytics: address Top posts widget review feedback

- package.json: use link: for internal @jetpack-premium-analytics/* deps
  (they are not pnpm workspace members)
- widget.ts: drop redundant `presentation` (owned by widget.json); add the
  `postType` attribute so the widget redefinition is complete
- render.tsx: rename the `name` attribute to `postType`; treat empty as "all
  types"; collapse the duplicated TopPostsLeaderboard JSDoc to @param {Type}

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AuSeh4kAoQvoKeXQbV2SLw

* Premium Analytics: move TopPostsAttributes type into widget.ts

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants