Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
531b9b4
Premium Analytics: add file-downloads widget
dognose24 Jun 29, 2026
7bf7dc9
Premium Analytics: changelog for file-downloads widget
dognose24 Jun 29, 2026
df174bf
Fix CI: Storybook tests — wrap LeaderboardChart stories in GlobalChar…
dognose24 Jun 29, 2026
f78ec5a
Address review: fix category to stats, document no-comparison intent
dognose24 Jun 29, 2026
b0db0ab
Premium Analytics: show file downloads comparison deltas
dognose24 Jun 29, 2026
2c14e22
Premium Analytics: align file downloads widget feedback
dognose24 Jun 30, 2026
3e46cae
Premium Analytics: Align file downloads widget stories
dognose24 Jun 30, 2026
a8a63eb
Add File Downloads to default dashboard
dognose24 Jul 1, 2026
c37fab0
Handle File Downloads Jetpack site errors
dognose24 Jul 1, 2026
23b1e97
Detect File Downloads unavailable errors
dognose24 Jul 1, 2026
73c66d4
Wrap File Downloads states with content padding
dognose24 Jul 1, 2026
5ab6c80
Center File Downloads placeholder states
dognose24 Jul 1, 2026
3c7f562
Merge remote-tracking branch 'origin/trunk' into add/wooa7s-1498-port…
dognose24 Jul 1, 2026
b2ccd7e
Premium Analytics: test file downloads dashboard layout
dognose24 Jul 1, 2026
7bf4a5b
Premium Analytics: fix stats mock lint
dognose24 Jul 1, 2026
b44b98f
Keep File Downloads header across states
dognose24 Jul 1, 2026
cd03921
Hide File Downloads title in close-up stories
dognose24 Jul 1, 2026
403e9eb
Use leaderboard empty state for unsupported file downloads
dognose24 Jul 1, 2026
143d6ec
Keep File Downloads errors on custom surface
dognose24 Jul 1, 2026
d4187fd
Add icon to File Downloads widget header
dognose24 Jul 1, 2026
27a6e67
Merge remote-tracking branch 'origin/trunk' into add/wooa7s-1498-port…
dognose24 Jul 2, 2026
e6a2181
Merge remote-tracking branch 'origin/trunk' into add/wooa7s-1498-port…
dognose24 Jul 2, 2026
b2ff78d
Guard File Downloads comparison rows
dognose24 Jul 2, 2026
d9f6bc6
Fix File Downloads comparison formatting
dognose24 Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add file-downloads widget porting the Jetpack Stats File downloads module into Premium Analytics.
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**
* Stats API mock middleware for Storybook.
*
* Intercepts `@wordpress/api-fetch` requests to the PA Stats proxy and returns
* static fixture data so Stats-backed widgets render in Storybook without a
* live WordPress + WPCOM connection.
*/
/**
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import type { APIFetchMiddleware, APIFetchOptions } from '@wordpress/api-fetch';

const STATS_BASE = '/jetpack-premium-analytics/v1/proxy/v1.1/stats';
const DAY_IN_MS = 24 * 60 * 60 * 1000;

const MOCK_FILE_DOWNLOADS_FILES = [
{
relative_url: '/annual-report-2025.pdf',
filename: 'annual-report-2025.pdf',
download_url: 'https://example.com/annual-report-2025.pdf',
downloads: '3840',
},
{
relative_url: '/product-brochure.pdf',
filename: 'product-brochure.pdf',
download_url: 'https://example.com/product-brochure.pdf',
downloads: '2610',
},
{
relative_url: '/getting-started-guide.pdf',
filename: 'getting-started-guide.pdf',
download_url: 'https://example.com/getting-started-guide.pdf',
downloads: '1920',
},
{
relative_url: '/press-release-q1.docx',
filename: 'press-release-q1.docx',
download_url: 'https://example.com/press-release-q1.docx',
downloads: '1305',
},
{
relative_url: '/logo-assets.zip',
filename: 'logo-assets.zip',
download_url: 'https://example.com/logo-assets.zip',
downloads: '870',
},
];

const MOCK_FILE_DOWNLOADS_COMPARISON_FILES = [
{
relative_url: '/annual-report-2025.pdf',
filename: 'annual-report-2025.pdf',
download_url: 'https://example.com/annual-report-2025.pdf',
downloads: '3200',
},
{
relative_url: '/product-brochure.pdf',
filename: 'product-brochure.pdf',
download_url: 'https://example.com/product-brochure.pdf',
downloads: '2900',
},
{
relative_url: '/getting-started-guide.pdf',
filename: 'getting-started-guide.pdf',
download_url: 'https://example.com/getting-started-guide.pdf',
downloads: '1600',
},
{
relative_url: '/press-release-q1.docx',
filename: 'press-release-q1.docx',
download_url: 'https://example.com/press-release-q1.docx',
downloads: '1500',
},
{
relative_url: '/logo-assets.zip',
filename: 'logo-assets.zip',
download_url: 'https://example.com/logo-assets.zip',
downloads: '700',
},
];

const MOCK_FILE_DOWNLOADS = {
date: '2026-06-29',
period: 'day',
days: {
'2026-06-29': {
files: MOCK_FILE_DOWNLOADS_FILES,
other_downloads: 0,
total_downloads: 10545,
},
},
summary: {
files: MOCK_FILE_DOWNLOADS_FILES,
other_downloads: 0,
total_downloads: 10545,
},
};

const MOCK_FILE_DOWNLOADS_COMPARISON = {
date: '2026-05-30',
period: 'day',
days: {
'2026-05-30': {
files: MOCK_FILE_DOWNLOADS_COMPARISON_FILES,
other_downloads: 0,
total_downloads: 9900,
},
},
summary: {
files: MOCK_FILE_DOWNLOADS_COMPARISON_FILES,
other_downloads: 0,
total_downloads: 9900,
},
};

function getStatsMock( path: string ): unknown | null {
const subPath = path.slice( STATS_BASE.length ).split( '?' )[ 0 ];

if ( subPath.startsWith( '/file-downloads' ) ) {
return isComparisonRequest( path ) ? MOCK_FILE_DOWNLOADS_COMPARISON : MOCK_FILE_DOWNLOADS;
}

return null;
}

function getLocalDatePart( date: Date ) {
const year = date.getFullYear();
const month = String( date.getMonth() + 1 ).padStart( 2, '0' );
const day = String( date.getDate() ).padStart( 2, '0' );

return `${ year }-${ month }-${ day }`;
}

function isComparisonRequest( path: string ) {
const query = path.split( '?' )[ 1 ];
const date = query ? new URLSearchParams( query ).get( 'date' ) : null;

if ( ! date ) {
return false;
}

const today = getLocalDatePart( new Date() );
const daysFromToday = Math.floor( ( Date.parse( today ) - Date.parse( date ) ) / DAY_IN_MS );

return daysFromToday > 1;
}

const statsMocksMiddleware: APIFetchMiddleware = async ( options: APIFetchOptions, next ) => {
const requestPath = options.path ?? options.url ?? '';

if ( ! requestPath.startsWith( STATS_BASE ) ) {
return next( options );
}

const mock = getStatsMock( requestPath );
if ( mock !== null ) {
return mock;
}

// Unknown Stats path — return empty-but-valid response.
return { days: {} };
};

let registered = false;

/**
* Registers the Stats API mock middleware. Idempotent.
*/
export function registerStatsMocks(): void {
if ( registered ) {
return;
}
registered = true;
apiFetch.use( statsMocksMiddleware );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "@automattic/jetpack-premium-analytics-widget-file-downloads",
"version": "0.1.0-alpha",
"private": true,
"type": "module",
"dependencies": {
"@jetpack-premium-analytics/data": "link:../../packages/data",
"@jetpack-premium-analytics/widgets-toolkit": "link:../../packages/widgets-toolkit",
"@wordpress/i18n": "^6.9.0",
"@wordpress/icons": "^13.0.0",
"@wordpress/ui": "0.13.0",
"@wordpress/widget-primitives": "next"
}
}
Loading