Skip to content

Conversation

@kaeizen
Copy link
Contributor

@kaeizen kaeizen commented Nov 20, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Prevented duplicate background checks and improved polling logic for the download notice to avoid concurrent operations and unnecessary polls in the media library.
    • Improved installation/activation status transitions and now surface an activation action when appropriate to ensure correct install/activate flows.
  • Style

    • Adjusted download notice button sizing for more flexible layout.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 20, 2025

Walkthrough

Introduces a module-scoped polling guard to prevent concurrent status polls in the CIMO notice, adds an inMediaLibrary prop and media-library-aware lifecycle changes, tweaks CIMO notice button sizing, and adjusts server-side plugin status/action logic for install/activation flows.

Changes

Cohort / File(s) Summary
CIMO polling guard & media-library behavior
src/lazy-components/cimo/index.js
Added a module-scoped isPolling guard to avoid concurrent pollStatus calls; pollStatus sets and resets isPolling, stops after conditions (pollOnce, >=3 attempts, specific status transitions), mutates shared cimoData and window.stackable.cimo, and skips initial polling when inMediaLibrary is true. Added inMediaLibrary prop (default false) and adjusted action click / close flows to derive and potentially re-trigger polling.
CIMO styles
src/lazy-components/cimo/style.scss
Removed explicit width: 14px from the button inside .stk-cimo-notice; height remains 14px, allowing flexible horizontal sizing while preserving vertical layout.
Plugin activation status logic
src/welcome/useful-plugins.php
check_cimo_status now sets 'not_installed' when action is 'install' and plugin absent; for not-activated plugins, returns fixed 'installed' and, if action was 'install', populates response['action'] with an activation link (previously could return 'activating' or omit activation link).

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant UI
    participant CimoNotice as CimoDownloadNotice
    participant pollStatus
    participant Server as status check

    UI->>CimoNotice: mount (inMediaLibrary? true/false)
    alt not in media library
        CimoNotice->>pollStatus: start polling
    else in media library
        CimoNotice-->>pollStatus: skip initial poll
    end

    pollStatus->>pollStatus: check isPolling
    alt already polling
        pollStatus-->>CimoNotice: return early
    else start polling
        pollStatus->>Server: fetch status
        Server-->>pollStatus: status response
        pollStatus->>CimoNotice: update cimoData/state
        alt terminal conditions met (pollOnce / attempts / status transitions)
            pollStatus-->>CimoNotice: stop polling, update window.stackable.cimo
        else
            pollStatus->>pollStatus: schedule next attempt
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay special attention to src/lazy-components/cimo/index.js for race conditions around isPolling, correct reset in Promise.finally, shared cimoData mutation, and media-library mount/unmount flows.
  • Verify src/welcome/useful-plugins.php changes correctly produce response['action'] for install->activate flows and that status strings map consistently to frontend expectations.

Possibly related PRs

Poem

🐰 A little rabbit tapped the gate,
One poll at once — no tangled state.
In the library it waits its turn,
Buttons breathe, statuses learn.
Hooray for tidy hops and less sprawl! 🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: fixing the CIMO notice to display the correct status after closing the media library, which is the core objective across all file modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/cimo-notice-status-in-editor

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a72fc5 and abfaf08.

📒 Files selected for processing (1)
  • src/lazy-components/cimo/index.js (7 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/lazy-components/cimo/index.js (1)
src/components/image-control2/index.js (1)
  • CimoDownloadNotice (87-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: PHP 8.2 and WP 6.7.2
  • GitHub Check: PHP 8.2 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: PHP 7.3 and WP latest
  • GitHub Check: PHP 8.2 and WP 6.6.2
  • GitHub Check: build
🔇 Additional comments (5)
src/lazy-components/cimo/index.js (5)

40-44: Polling guard implementation looks good.

The polling guard correctly prevents concurrent requests while allowing scheduled retries. Setting isPolling = false on line 57 enables the next scheduled poll, and the .finally() block on line 99 provides a safety net.

Note: The assignment on line 57 makes the one in .finally() redundant for success cases, but this redundancy is harmless and provides additional safety if errors occur during response processing.

Also applies to: 56-57, 95-100


75-81: LGTM!

The polling termination logic correctly handles both install and activate completion states, and properly synchronizes the module-level cimoData, component state, and global window.stackable.cimo object.


104-107: LGTM!

The media library lifecycle handling is well-designed:

  • Skipping frame setup when already in media library prevents redundant handler registration
  • Status-to-action mapping correctly derives the polling action from the current status
  • Syncing state when the media library closes ensures the editor reflects the latest status

Also applies to: 119-127


138-146: LGTM!

The action handlers correctly update both the module-level cimoData and component state, ensuring consistency across instances. The isPolling guard prevents race conditions if actions are triggered from multiple instances simultaneously.


206-206: LGTM!

Correctly passes inMediaLibrary={ true } to the notice component when rendering inside the media library, ensuring the instance skips the media library frame setup.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kaeizen kaeizen self-assigned this Nov 20, 2025
@github-actions
Copy link

github-actions bot commented Nov 20, 2025

🤖 Pull request artifacts

file commit
pr3642-stackable-3642-merge.zip abfaf08

github-actions bot added a commit that referenced this pull request Nov 20, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/welcome/useful-plugins.php (1)

289-304: Status not_installed is returned without an action URL, which breaks the "Install now" link after a failed install

When user_action === 'install' and the plugin is still not installed, you now return:

$response['status'] = 'not_installed';

but you never set $response['action']. On the frontend, pollStatus does setData( res.data ), so data.action becomes ''. The UI then renders an <a> for the "Install now" state with an empty href, so after a failed/aborted install the user sees "Install now" but the link is no longer usable.

Two concrete improvements:

  1. Return a valid install URL when reporting not_installed (mirroring add_cimo_args_to_localize_editor):
if ( $action === 'install' && ! self::is_plugin_installed( $full_slug ) ) {
-	$response['status'] = 'not_installed';
+	$response['status'] = 'not_installed';
+	$response['action'] = html_entity_decode( wp_nonce_url(
+		add_query_arg(
+			[
+				'action' => 'install-plugin',
+				'plugin' => $slug,
+			],
+			admin_url( 'update.php' )
+		),
+		'install-plugin_' . $slug
+	) );
} else if ( ! self::is_plugin_activated( $full_slug ) ) {
  1. Optionally, consider what should happen when $action === 'activate' but the plugin is actually not installed. Currently this path also falls into the ! self::is_plugin_activated() branch and reports status = 'installed', which is misleading; you may want to report not_installed there as well or treat it as an error.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9338467 and 3a72fc5.

📒 Files selected for processing (3)
  • src/lazy-components/cimo/index.js (5 hunks)
  • src/lazy-components/cimo/style.scss (0 hunks)
  • src/welcome/useful-plugins.php (1 hunks)
💤 Files with no reviewable changes (1)
  • src/lazy-components/cimo/style.scss
🧰 Additional context used
🧬 Code graph analysis (1)
src/lazy-components/cimo/index.js (1)
src/components/image-control2/index.js (1)
  • CimoDownloadNotice (87-87)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: PHP 8.2 and WP 6.7.2
  • GitHub Check: PHP 8.2 and WP 6.5.5
  • GitHub Check: PHP 8.2 and WP 6.6.2
  • GitHub Check: PHP 8.2 and WP latest
  • GitHub Check: PHP 7.3 and WP latest
  • GitHub Check: PHP 7.3 and WP 6.5.5
  • GitHub Check: build
🔇 Additional comments (1)
src/lazy-components/cimo/index.js (1)

17-17: inMediaLibrary prop wiring correctly scopes media-frame side effects

The new inMediaLibrary prop and its usage look sound:

  • Line 17: const { inMediaLibrary = false } = props keeps existing callers unchanged.
  • Lines 102–105: early return from useEffect when inMediaLibrary is true prevents re‑patching wp.media.view.MediaFrame.Select from inside the media library context.
  • Line 203: media library injection correctly passes inMediaLibrary={ true } when rendering CimoDownloadNotice.

This should avoid double‑binding media frame events while preserving the original behavior for the editor notice.

Also applies to: 102-105, 203-203

github-actions bot added a commit that referenced this pull request Nov 20, 2025
github-actions bot added a commit that referenced this pull request Nov 21, 2025
@bfintal bfintal merged commit b9b0d41 into develop Nov 21, 2025
8 of 9 checks passed
@bfintal bfintal deleted the fix/cimo-notice-status-in-editor branch November 21, 2025 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants