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

My Jetpack: Add red bubble and notice when paid plan needs plugin install or activation. #41013

Merged

Conversation

elliottprogrammer
Copy link
Contributor

@elliottprogrammer elliottprogrammer commented Jan 14, 2025

This PR adds a red-bubble and notice-banner when the site detects that a paid plan provides features to a plugin (or multiple plugins) that are not installed and/or activated. The notice recommends that the plugin(s) should be installed and/or activated and provides a CTA to install and activate all in one click.
To summarize, basically it adds a red-bubble and notice for missing plugins that are needed for purchased products to work. See screenshot:

Screen Shot 2025-01-16 at 10 48 54

Fixes: https://github.com/Automattic/jetpack-roadmap/issues/1393
Fixes: #35593

Other information:

  • Have you written new tests for your changes, if applicable?
  • Have you checked the E2E test CI results, and verified that your changes do not break them?
  • Have you tested your changes on WordPress.com, if applicable (if so, you'll see a generated comment below with a script to run)?

Jetpack product discussion

Project Thread - pbNhbs-bJN-p2
Github Task - https://github.com/Automattic/jetpack-roadmap/issues/1393

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

No

Testing instructions:

  • It's best to test this PR with a Jurassic Ninja site (using the Jetpack Beta plugin), as opposed to a local dev site (because a local dev site already has all Jetpack plugins installed via the nature of the monorepo).
  • Connect Jetpack (both site and user).
  • Purchase the Jetpack Complete plan for the site.
  • In My Jetpack, you should see a red-bubble and notice, stating Some plugins need installation. (See screenshot above in the description ⤴️)
  • Verify all the links in the notice. The "Jetpack Complete paid subscription" link should point to the Calypso green purchases Complete subscription page. The Jetpack Boost and Jetpack CRM plugin links should point to their respective plugins page on wordpress.org
  • Click the "install and activate plugins in one click" CTA. The CTA loading text should say, "Installing and activating plugins...".
  • After a few moments (after the plugins are installed and activated) the banner should disappear, and a global notice (toast/snackbar popup) in the top right corner saying "Plugin(s) installed successfully!".
  • Verify that the Jetpack Boost and CRM plugins are showing as active in My Jetpack and confirm they have been installed and activated.
  • If desired, you can try other paid plan with a missing (or un-activated) plugin(s) combinations. For example, with only a standalone plugin installed, (the main Jetpack plugin Not installed), purchase a Jetpack AI plan. Verify a red bubble and notice appear stating that the Jetpack plugin should be installed in order for Jetpack AI to work properly.
  • The notice will also appear if required plugins are installed but merely not activated, or a combination of both (not installed OR installed but not activated), so you can test Not activated plugins also, if you want.

@elliottprogrammer elliottprogrammer self-assigned this Jan 14, 2025
Copy link
Contributor

github-actions bot commented Jan 14, 2025

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 WordPress.com Simple 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, and enable the add/mj-red-bubble-notice-when-plugins-need-installed branch.

  • To test on Simple, run the following command on your sandbox:

    bin/jetpack-downloader test jetpack add/mj-red-bubble-notice-when-plugins-need-installed
    

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

Copy link
Contributor

github-actions bot commented Jan 14, 2025

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 Team Review, ...).
  • 🔴 Add a "[Type]" label (Bug, Enhancement, Janitorial, Task).
  • ✅ 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 🤖


The e2e test report can be found here. Please note that it can take a few minutes after the e2e tests checks are complete for the report to be available.


Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Choose a review path based on your changes:
    • A. Team Review: add the "[Status] Needs Team Review" label
      • For most changes, including minor cross-team impacts.
      • Example: Updating a team-specific component or a small change to a shared library.
    • B. Crew Review: add the "[Status] Needs Review" label
      • For significant changes to core functionality.
      • Example: Major updates to a shared library or complex features.
    • C. Both: Start with Team, then request Crew
      • For complex changes or when you need extra confidence.
      • Example: Refactor affecting multiple systems.
  3. Get at least one approval before merging.

Still unsure? Reach out in #jetpack-developers for guidance!


Protect plugin:

  • Next scheduled release: none scheduled.

If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack.

@github-actions github-actions bot added the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 14, 2025
@elliottprogrammer elliottprogrammer requested a review from a team January 16, 2025 19:48
@elliottprogrammer elliottprogrammer added [Status] Needs Team Review and removed [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! labels Jan 16, 2025
@github-actions github-actions bot added the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 16, 2025
Copy link
Contributor

@CodeyGuyDylan CodeyGuyDylan left a comment

Choose a reason for hiding this comment

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

I am not sure why, but when running through the testing instructions with 0 standalone plugins installed, I am only seeing "CRM" as a missing plugin, not Boost
image

After clicking the CTA, just as described, the banner disappears after installing the plugins (FYI it also only installed CRM, not Boost). I think this could be jarring for users. Like ".... okay? did it work?" I think it would be much better for the user experience if we had a success message after letting them know the plugins were installed. I see that this PR is pretty large already, if you'd like to handle that separately I think that'd be okay

I found a bug during testing, and I can't really tell what it causing it from the browser testing site as it seems to be PHP related. I get a critical error like this:
image

Steps to reproduce:

  1. Uninstall main Jetpack plugin
  2. Install standalone Boost plugin
  3. With the beta tester, checkout this branch for the Boost plugin
  4. Go to My Jetpack

I tried these steps with the stable version of boost and it's not happening so I assume it has to do with this PR. There could be other similar situations where this error takes place, I haven't yet tested all possibilities

public static function activate_multiple_products( $request ) {
$products_array = $request->get_param( 'products' );

foreach ( $products_array as $product_slug ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I have some thoughts on the notion that we need to create separate plugin endpoints for activating multiple products like this 🤔

If we had a function to bulk activate or install plugins without requiring multiple actions, I would understand it. However, it looks like here we are essentially doing the same thing as activate_product with the only difference being we are looping through an array of product slugs instead of just handling one product slug.

I could be missing something that makes my approach not the best way to go, but I think it may be better to alter the activate_product endpoint to optionally accept multiple products. It may require a re-naming to just activate_products but I think it would simplify the changes on the backend by a lot, and then on the front-end we wouldn't need the new hooks that handle multiple products that and calls a different endpoint. Let me know what you think of this, hopefully that could make this PR much smaller and simpler 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @CodeyGuyDylan ! Yeah I agree it would be ideal to have a shared endpoint for activating either 1 product or multiple products, but the way the My Jetpack REST endpoints are currently set up are:

Activate endpoint:
Path: /my-jetpack/v1/site/products/{PRODUCT_SLUG}
If it's a GET request: get_product()
If it's a POST request: activate_product()
if it's a DELETE request: deactivate_product()

Install endpoint:
Path: /my-jetpack/v1/site/products/{PRODUCT_SLUG}/install-standalone

So as you can see, the the endpoint route/path takes in 1 product_slug as part of the endpoint path.
Therefore I don't see how we can use that endpoint for doing anything with multiple products because we can't put multiple product slugs into the endpoint route/path, unless I'm missing something, let me know.
So that's why I had to create new endpoints. I'm not sure how else I could do it.

@elliottprogrammer
Copy link
Contributor Author

Thanks for reviewing @CodeyGuyDylan!

I found a bug during testing, and I can't really tell what it causing it from the browser testing site as it seems to be PHP related. I get a critical error like this:

The bug was fixed in: #41192

I am not sure why, but when running through the testing instructions with 0 standalone plugins installed, I am only seeing "CRM" as a missing plugin, not Boost

Hmm, that is really strange, I'm not able to reproduce that. The only think I can think to do is maybe try a new JN site? 🤷‍♂️ Or maybe it has something to do with the bug mentioned above (that is now fixed)?

I think it would be much better for the user experience if we had a success message after letting them know the plugins were installed.

I added a Global Notice (a toast/snackbar popup) after the CTA action (plugins installed/activated) completes successfully. Let me know if this improves the user experience the way you had in mind.

I have some thoughts on the notion that we need to create separate plugin endpoints for activating multiple products like this 🤔

I responded to this in the inline code comments. Let me know your thoughts. 🙂

@elliottprogrammer elliottprogrammer requested review from CodeyGuyDylan and a team January 23, 2025 15:38
@elliottprogrammer elliottprogrammer removed the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 23, 2025
@github-actions github-actions bot added the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 23, 2025
@github-actions github-actions bot added the [Plugin] Protect A plugin with features to protect a site: brute force protection, security scanning, and a WAF. label Jan 24, 2025
@elliottprogrammer
Copy link
Contributor Author

@CodeyGuyDylan, I've refactored and cleaned up the My Jetpack Product endpoints, allowing them to act upon multiple products, and removed any endpoints that were strictly limited to acting upon only a single product, then updated the front-end to work with these changes. Also updated PHP tests.
When you have a chance, the PR is ready for review again. Thanks Dylan! 🙌

@elliottprogrammer elliottprogrammer removed the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 24, 2025
@github-actions github-actions bot added the [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! label Jan 27, 2025
Copy link
Contributor

@CodeyGuyDylan CodeyGuyDylan left a comment

Choose a reason for hiding this comment

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

This looks very good!

I did find one strange bug where the Jetpack plugin shows up twice as needing installed
image

Steps to reproduce

  1. Install only the Jetpack Boost standalone plugin
  2. Purchase Jetpack Complete
  3. Go to My Jetpack

Not sure what's causing that, but perhaps a check to make sure every item in the list is unique would fix it? FYI the activation of the plugins does still work, so that's a plus 😄

I left 2 other comments, one being very minor, but thank you for doing the work to update this PR. I think it's looking great and is almost ready

return isPluginActive;
};

const useActivatePlugins = ( productIds: string[] ) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think a QOL improvement for developers would be to allow either the string[] or string type, and just convert the string to an array automatically if it is not already one. That way we don't have to pass in [ slug ] everywhere we activate only one plugin at a time. Same with the useInstallPlugins and useProducts hooks. Do you think that would be a good idea?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, thats a good idea, thanks! 👍


$response = $this->server->dispatch( $request );
$data = $response->get_data();
print_r( $data );
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we have a leftover testing line here 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, thanks for catching that!

@elliottprogrammer
Copy link
Contributor Author

@CodeyGuyDylan, Thanks again for reviewing and for your feedback!
Ok, I've addressed the following:

  • Filtered out displaying any duplicate plugins (in the notice/banner) that may need installed or activated.
  • Allow useActivatePlugins, useInstallPlugins, and useProducts hooks to accept a string or string[] (array).
  • Removed unintentional, left-over print_r( $data ).

I really appreciate all your time, attention, and effort with reviewing this PR (and all the PR's of this project!) 🙌

Copy link
Contributor

Code Coverage Summary

Coverage changed in 7 files. Only the first 5 are listed here.

File Coverage Δ% Δ Uncovered
projects/packages/my-jetpack/src/class-initializer.php 52/495 (10.51%) -0.47% 21 💔
projects/packages/my-jetpack/src/class-rest-products.php 126/184 (68.48%) -0.59% 15 💔
projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/index.ts 0/10 (0.00%) 0.00% 1 💔
projects/packages/my-jetpack/src/class-products.php 62/142 (43.66%) 2.18% 1 💔
projects/packages/my-jetpack/src/products/class-jetpack-ai.php 90/249 (36.14%) 0.40% -1 💚

6 files are newly covered. Only the first 5 are listed here.

File Coverage
projects/packages/my-jetpack/_inc/data/products/use-activate-plugins.ts 0/26 (0.00%) 💔
projects/packages/my-jetpack/_inc/data/products/use-install-plugins.ts 0/9 (0.00%) 💔
projects/packages/my-jetpack/_inc/data/products/use-products.ts 0/15 (0.00%) 💔
projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-paid-plan-needs-plugin-install-activation-notice.tsx 0/68 (0.00%) 💔
projects/packages/my-jetpack/_inc/data/products/use-all-products.ts 5/6 (83.33%) 💚

Full summary · PHP report · JS report

Copy link
Contributor

@CodeyGuyDylan CodeyGuyDylan left a comment

Choose a reason for hiding this comment

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

I'm getting an issue where, if I have Complete and only Boost installed, I click the CTA and it doesn't install all the plugins it listed out in the banner. It seemed to stop after it downloaded the main Jetpack plugin. Then when I uninstall that, the banner shows me the main plugin plus the standalone's it didn't install last time. I don't think this is blocking as all the products will work (as far as I can tell) after clicking the CTA and the banner will go away.

@elliottprogrammer elliottprogrammer merged commit 8ffa52d into trunk Jan 28, 2025
78 checks passed
@elliottprogrammer elliottprogrammer deleted the add/mj-red-bubble-notice-when-plugins-need-installed branch January 28, 2025 21:51
@github-actions github-actions bot removed [Status] Needs Author Reply We would need you to make some changes or provide some more details about your PR. Thank you! [Status] Needs Team Review labels Jan 28, 2025
sprintf(
/* translators: %s is the word "Plugin" or "Pluigns" (singular or plural). */
__( '%s installed successfully!', 'jetpack-my-jetpack' ),
products?.length === 1 ? products[ 0 ].title : __( 'Plugins', 'jetpack-my-jetpack' )
Copy link

@emilyaudela emilyaudela Feb 11, 2025

Choose a reason for hiding this comment

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

Would it be possible to update the plural strings to account for localization? Instead of "'%s installed successfully!", we would prefer 2 strings or a proper plural:

  • plugin installed successfully!
  • plugins installed successfully!

In many languages, the words will need to change depending on whether the word "plugin" is singular or plural.

There are many instances of this in this PR. If it's not changed, some languages will not read correctly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hey @emilyaudela 👋!
Thanks for your feedback! Yes! Thank you! I'll get it fixed asap. 👍🙂

Copy link
Contributor Author

@elliottprogrammer elliottprogrammer Feb 11, 2025

Choose a reason for hiding this comment

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

Oh wait... yeah the translation comment is incorrect. The %s is not the word "Plugin" or "Plugins", but rather %s is the Jetpack product name, i.e.- VaultPress Backup or Boost or Social or Search or VideoPress, etc. if it's in the singular context, or %s is the word "Plugins" if it's in the plural context.
So yeah, anyway still, I'll fix the translation comment and make it 2 separate strings (or proper plural, whichever seems to be the best approach). 👍

Copy link
Contributor Author

@elliottprogrammer elliottprogrammer Feb 12, 2025

Choose a reason for hiding this comment

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

I've created PR #41756 which separates the above translations into separate strings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] My Jetpack [Plugin] Protect A plugin with features to protect a site: brute force protection, security scanning, and a WAF. [Tests] Includes Tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

My Jetpack: better outline Backup errors in the VaultPress backup card
3 participants