Skip to content

Eligibility warnings: show only the blocking notice when a transfer is in progress - #113952

Open
bcotrim wants to merge 2 commits into
trunkfrom
dotdev-444-second-plugin-during-atomic-transfer-message
Open

Eligibility warnings: show only the blocking notice when a transfer is in progress#113952
bcotrim wants to merge 2 commits into
trunkfrom
dotdev-444-second-plugin-during-atomic-transfer-message

Conversation

@bcotrim

@bcotrim bcotrim commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes DOTDEV-444

Proposed Changes

  • When the eligibility check returns a hard-blocking hold (e.g. TRANSFER_ALREADY_EXISTS while an Atomic transfer is running), render only the blocking notice and the support link — the dimmed "To continue you'll need to:" hold list and the disabled Continue button are no longer shown.
  • Show the blocking notice in every context, not just plugin-details.
  • Remove the now-dead dim/disable logic in hold-list.tsx and the eligibility-warnings__hold-list-dim styles; add spacing between the notice and the support link.
  • The Atomic-below-Business exception is preserved: those sites still see the upgrade hold list with an enabled "Upgrade and continue".
Before After
image image

Why are these changes being made?

  • Installing a second plugin while the first install's Atomic transfer is still running showed a contradictory modal: an "Installation in progress, please wait" notice on top of a greyed-out (and in the plugin-details context, empty) checklist and a dead Continue button. When the only possible action is to wait, the modal now says just that.

Testing Instructions

  1. Use a Simple site on a plan that allows plugin installs, with no prior Atomic transfer.
  2. In Calypso, open a plugin page and click Install, then Continue — this starts the Atomic transfer. Close the progress screen.
  3. While the transfer is still running, open a different plugin and click Install.
  4. The "One more step" modal shows only the "Installation in progress…" notice and the "Need help?" link — no "To continue you'll need to:" checklist, no Continue button.

Regression checks:

  • blocked_atomic_transfer hold → error notice with "Contact us", no Continue button.
  • Atomic site on a plan below Business (transfer_already_exists + no_business_plan) → unchanged: upgrade hold list with enabled "Upgrade and continue".
  • No holds / warnings only → unchanged eligibility flow with a working Continue button.

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?
  • For UI changes, have you tested the affected components in dark mode?
  • Have you tested accessibility for your changes? Ensure the feature remains usable with various user agents (e.g., browsers), interfaces (e.g., keyboard navigation), and assistive technologies (e.g., screen readers) (PCYsg-S3g-p2).
  • 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)?

@bcotrim bcotrim self-assigned this Aug 31, 2026
@github-actions

Copy link
Copy Markdown

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

Sections (~277 bytes removed 📉 [gzipped])

Details
Name Parsed Gzip
a8c-for-agencies-plugins -256 B -0.0% -74 B -0.0%
a8c-for-agencies-sites -256 B -0.0% -68 B -0.0%
github-deployments -256 B -0.0% -67 B -0.0%
site-logs -256 B -0.0% -67 B -0.0%
site-performance -256 B -0.0% -67 B -0.0%
site-monitoring -256 B -0.0% -67 B -0.0%
jetpack-cloud-plugin-management -256 B -0.0% -74 B -0.0%
scan -256 B -0.0% -68 B -0.0%
backup -256 B -0.0% -68 B -0.0%
theme -256 B -0.0% -71 B -0.0%
themes -256 B -0.0% -74 B -0.0%
hosting -256 B -0.0% -67 B -0.0%
settings-performance -256 B -0.0% -74 B -0.0%
plugins -256 B -0.0% -74 B -0.0%
marketplace -252 B -0.0% -77 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.

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.

@bcotrim
bcotrim requested a review from a team August 31, 2026 17:49
@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 Aug 31, 2026
@bcotrim
bcotrim marked this pull request as ready for review August 31, 2026 17:49
@fredrikekelund

Copy link
Copy Markdown
Contributor

I'm reviewing this now, fyi

@fredrikekelund fredrikekelund 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.

First and foremost: I tested this, and it fixes the issue 👍

However, looking at the code made me confused. The hold list is being used for several different purposes at different levels. It's filtered, it's searched for blocking holds, it's used for conditional rendering both in the EligibilityWarnings parent and the HardBlockingNotice child.

The way I read it, there are a few things making the logic unnecessarily complex right now:

  • There's a legacy assumption about plans below Business not supporting plugins, which is no longer true. I assume this means the API just no longer returns NO_BUSINESS_PLAN for those sites. We probably leave the core front-end logic as is, but the naming does add confusion, IMO.
  • The relationship between HardBlockingNotice and HoldList is unclear. I asked if we should only ever render one at a time, but that's quite hard to decipher right now.
  • We changed EligibilityWarnings to only render HardBlockingNotice if hasValidBlockingHold is true. However, inside HardBlockingNotice, the first thing we do is invert that logic and return null is it's true. We should conditionally render this component either outside or inside (the right answer is probably outside).
  • We only render HoldList if ! hasValidBlockingHold. Do we still need to also construct and check filteredHold..? It looks kind of redundant to me, even if it's difficult to say for sure from the code alone.

{ ! isPlaceholder && context === 'plugin-details' && hasBlockingHold( listHolds ) && (
{ ! isPlaceholder && hasValidBlockingHold && (
<CompactCard>
<HardBlockingNotice

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.

Are HardBlockingNotice and HoldList supposed to ever render side by side?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants