Skip to content
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

Odyssey Stats: Fix redirection with query string for custom date range #97658

Merged
merged 7 commits into from
Dec 29, 2024

Conversation

dognose24
Copy link
Contributor

@dognose24 dognose24 commented Dec 19, 2024

Follow-up of fixing redirection on Odyssey Stats from #97591.

Proposed Changes

  • Refactor the appendQueryStringForRedirection function to append the query string for redirection on Odyssey Stats.
  • Fix applying stored period and date range shortcut on Odyssey Stats.

Why are these changes being made?

  • The custom date range is only available on context.query rather than window.location.search for Odyssey Stats. So, the redirection that happens on Odyssey Stats may need an extra query object parsing process.

Testing Instructions

  • Spin this change up with the local self-hosted site: cd /some-path-to/wp-calypso/apps/odyssey-stats && STATS_PACKAGE_PATH=/some-path-to/jetpack/projects/packages/stats-admin yarn dev.
  • Navigate to Stats > Traffic page.
  • Open the date range picker.
  • Click on the Yesterday shortcut.
  • Ensure the page is redirected to the hourly view for Yesterday.

Before the change

2024-12-20.12.52.00.mov

After the change

2024-12-20.12.55.13.mov
  • Select the chart period to Weeks and a date range shortcut other than the default Last 7 Days.
  • Click on the sidebar Stats item.
  • Ensure the default Stats view applies the stored chart period and date range shortcut.
2024-12-20.12.59.54.mov

Pre-merge Checklist

  • Has the general commit checklist been followed? (PCYsg-hS-p2)
  • Have you written new tests for your changes?
  • Have you tested the feature in Simple (P9HQHe-k8-p2), Atomic (P9HQHe-jW-p2), and self-hosted Jetpack sites (PCYsg-g6b-p2)?
  • Have you checked for TypeScript, React or other console errors?
  • Have you used memoizing on expensive computations? More info in Memoizing with create-selector and Using memoizing selectors and Our Approach to Data
  • Have we added the "[Status] String Freeze" label as soon as any new strings were ready for translation (p4TIVU-5Jq-p2)?
    • For UI changes, have we tested the change in various languages (for example, ES, PT, FR, or DE)? The length of text and words vary significantly between languages.
  • For changes affecting Jetpack: Have we added the "[Status] Needs Privacy Updates" label if this pull request changes what data or activity we track or use (p4TIVU-aUh-p2)?

@dognose24 dognose24 added the [Feature] Stats Everything related to our analytics product at /stats/ label Dec 19, 2024
@dognose24 dognose24 requested a review from a team December 19, 2024 17:02
@dognose24 dognose24 self-assigned this Dec 19, 2024
@matticbot matticbot added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Dec 19, 2024
@dognose24 dognose24 added the Odyssey Stats Calypso Stats in Jetpack label Dec 19, 2024
@matticbot
Copy link
Contributor

matticbot commented Dec 19, 2024

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

Sections (~4 bytes removed 📉 [gzipped])

name   parsed_size           gzip_size
stats        +16 B  (+0.0%)       -4 B  (-0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~35 bytes added 📈 [gzipped])

name                                       parsed_size           gzip_size
async-load-store-app-store-stats-listview        +95 B  (+0.1%)      +35 B  (+0.1%)
async-load-store-app-store-stats                 +95 B  (+0.0%)      +35 B  (+0.0%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@dognose24 dognose24 requested a review from a8ck3n December 19, 2024 17:06
@@ -918,7 +926,8 @@ export default connect(
supportUserFeedback,
} = getEnvStatsFeatureSupportChecks( state, siteId );

const hasSiteLoadedFeatures = hasLoadedSiteFeatures( state, siteId );
// Odyssey Stats does not need loading features to determine gated features.
const hasSiteLoadedFeatures = hasLoadedSiteFeatures( state, siteId ) || isOdyssey;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const hasSiteLoadedFeatures = hasLoadedSiteFeatures( state, siteId ) || isOdyssey;
const hasSiteLoadedFeatures = isOdyssey || hasLoadedSiteFeatures( state, siteId );

If we swap these conditions, we'll avoid calling the function at all inside Odyssey.

@@ -326,6 +326,7 @@ class StatsSite extends Component {
isJetpack,
isSitePrivate,
isOdysseyStats,
isOdyssey,
Copy link
Contributor

@a8ck3n a8ck3n Dec 20, 2024

Choose a reason for hiding this comment

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

This is a bit confusing having both isOdyssey and isOdysseyStats here. Is this the case where one represents API routing vs direct calls to wpcom? If so, we should probably rename it now to avoid confusion.

Update: I see two more instances of this below confirming the above comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If so, we should probably rename it now to avoid confusion.

I think so. That would be the refactoring work, as we will tackle them all at once later. Context: p1733887222490759-slack-C82FZ5T4G.

Copy link
Contributor

Choose a reason for hiding this comment

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

My bad, maybe isWPAdmin a better name for isOdyssey?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed in c0df942.

Copy link
Contributor

@a8ck3n a8ck3n left a comment

Choose a reason for hiding this comment

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

This doesn't quite work correctly in my testing. I'm seeing that in some cases, the page=stats is added to the params twice. Then, if the user refreshes the page, the browser tries to encode the parameter list. I end up seeing the following:

?page%5B0%5D=stats&page%5B1%5D=stats&chartStart=2024-12-20&chartEnd=2024-12-20

That decodes to:

?page[0]=stats&page[1]=stats

So it appears the browser is trying to number the duplicate params?

I think the fix is probably to dedupe the params before updating the string maybe?

const queryString = isOdyssey && query ? `&${ new URLSearchParams( query ).toString() }` : '';

return `${ baseUrl }${ queryString }`;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

I tested the following and it's working in my testing.

export const parseQueryStringForOdysseyRedirect = ( baseUrl, isOdyssey, query = {} ) => {
	const newParams = new URLSearchParams( window.location.search );
	if ( isOdyssey ) {
		const queryParams = new URLSearchParams( query );
		queryParams.forEach( ( value, key ) => {
			newParams.set( key, value );
		} );
	}

	return `${ baseUrl }?${ newParams.toString() }`;
};

We'd then need to upate the two call sites to not include window.location.search in the base URL value.

What do you think?

Copy link
Contributor Author

@dognose24 dognose24 Dec 20, 2024

Choose a reason for hiding this comment

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

I would not prefer to make the function process inputs along with a global variable simultaneously, which would make it quite MAGIC.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, good point. We could make the window.location.search a passed-in value to avoid that. BUT… @kangzj 's comment below about not using window.location.search at all probably makes more sense.

@dognose24
Copy link
Contributor Author

the page=stats is added to the params twice.

I saw it when testing, but reproducing it was not easy. Could you provide a way to reproduce it constantly?

@dognose24 dognose24 requested a review from kangzj December 23, 2024 12:49
@matticbot
Copy link
Contributor

matticbot commented Dec 23, 2024

This PR modifies the release build for the following Calypso Apps:

For info about this notification, see here: PCYsg-OT6-p2

  • command-palette-wp-admin
  • help-center
  • notifications
  • odyssey-stats

To test WordPress.com changes, run install-plugin.sh $pluginSlug update/stats_fix_redirection_query_string_for_odyssey on your sandbox.

isWpAdmin && context.query ? `&${ new URLSearchParams( context.query ).toString() }` : '';
const url = `/stats/day/${ context.params.module }/${ context.params.site }${ window.location.search }${ query }`;
const url = parseQueryStringForOdysseyRedirect(
`/stats/day/${ context.params.module }/${ context.params.site }${ window.location.search }`,
Copy link
Contributor

Choose a reason for hiding this comment

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

We might not need ${ window.location.search } here, which probably caused the issue of multiple page=stats issue.

I think we could use query, path and/or pathname from context, which are unified in both Odyssey and Calypso, which apparently I missed when adding the redirection logic.

Copy link
Contributor Author

@dognose24 dognose24 Dec 27, 2024

Choose a reason for hiding this comment

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

Sounds good to me!

Copy link
Contributor Author

@dognose24 dognose24 Dec 29, 2024

Choose a reason for hiding this comment

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

It seems we only need the base pathname and append the context.query params string to it, which works on both Caylpso and Odyssey Stats. Updated in 0fc48b5.

@a8ck3n
Copy link
Contributor

a8ck3n commented Dec 26, 2024

I saw it when testing, but reproducing it was not easy. Could you provide a way to reproduce it constantly?

So I tested this again today. It's very easy to reproduce for me. The steps are:

  1. Visit Stats → Traffic. Should default to 7-day view.
  2. Select Yesterday shortcut and apply.
  3. The URL should update and show ?page=stats&page=stats in the URL params.
  4. If the user refreshes the page via "command-R" or the refresh button in the browser, they'll see the URL encoded version noted above. — ?page%5B0%5D=stats&page%5B1%5D=stats&chartStart=2024-12-20&chartEnd=2024-12-20

The actual full URL I'm seeing is this:

https://hanabi.ap.ngrok.io/wp-admin/admin.php?page=stats#!/stats/hour/hanabi.ap.ngrok.io?page=stats&page=stats&chartStart=2024-12-25&chartEnd=2024-12-25

So page=stats is in there three times but it's only the bits after the #! that are relevant here, I think.

@dognose24
Copy link
Contributor Author

I updated the URL path processor to use the base pathname and append the query string from context.query to it, which seems to work for both Calypso and Odyssey Stats.

@dognose24 dognose24 requested review from a8ck3n and kangzj December 29, 2024 17:59
Copy link
Contributor

@kangzj kangzj left a comment

Choose a reason for hiding this comment

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

Works well and looks good 👍

@kangzj kangzj merged commit 1bb823f into trunk Dec 29, 2024
14 checks passed
@kangzj kangzj deleted the update/stats_fix_redirection_query_string_for_odyssey branch December 29, 2024 22:20
@github-actions github-actions bot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Dec 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Stats Everything related to our analytics product at /stats/ Odyssey Stats Calypso Stats in Jetpack
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants