Skip to content

feat(bulk-editor): add pending-changes guard seam for external plugins#23405

Draft
thijsoo wants to merge 2 commits into
feature/bulk-editorfrom
1297-premium-fe-5-bulk-editor-ai-suggested-pending-changes-alert
Draft

feat(bulk-editor): add pending-changes guard seam for external plugins#23405
thijsoo wants to merge 2 commits into
feature/bulk-editorfrom
1297-premium-fe-5-bulk-editor-ai-suggested-pending-changes-alert

Conversation

@thijsoo

@thijsoo thijsoo commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Context

The bulk editor already guards a tab switch (Search ↔ Social) when there are unsaved manual inline edits, via UnsavedChangesModal. Premium needs the same guard for unapplied AI suggestions, but the tab-switch logic lives entirely in Free and has no knowledge of an add-on's state. This PR adds a small, reactive seam so an add-on can defer a tab switch and supply its own confirmation modal.

Summary

This PR can be summarized in the following changelog entry:

  • Adds an extension point so add-ons can guard bulk editor tab switches for their own pending changes. (non-user-facing in Free; the user-facing behaviour ships in Yoast SEO Premium.)

Relevant technical choices:

  • New externalPendingChanges store boolean with a setHasExternalPendingChanges action and selectHasExternalPendingChanges selector, registered on the @yoast/bulk-editor store.
  • onChangeTab now defers the switch when the flag is set (manual edits keep precedence); a new PENDING_CHANGES_MODAL_SLOT (yoast.bulkEditor.pendingChangesModal) is rendered with fillProps { isOpen, onCommit, onCancel } for the add-on to fill.
  • A self-healing effect completes a deferred switch if its guard clears, so pendingTab can never be stranded with no modal to resolve it.

Test instructions

Test instructions for the acceptance test before the PR gets merged

This is a non-user-facing seam; on its own (Free only) it must not change existing behaviour. The user-visible behaviour is tested via the Premium PR.

  1. Go to Tools → Bulk editor and pick a content type.
  2. Edit a field inline, then click the other appearance tab (Search/Social) → the existing Unsaved changes modal still appears and behaves as before.
  3. With no edits, switching tabs still happens immediately.

Relevant test scenarios

  • Changes should be tested with the browser console open
  • Changes should be tested on different posts/pages/taxonomies/custom post types/custom taxonomies
  • Changes should be tested on different editors (Default Block/Gutenberg/Classic/Elementor/other)
  • Changes should be tested on different browsers
  • Changes should be tested on multisite

Test instructions for QA when the code is in the RC

Not applicable — non-user-facing seam; the user-visible behaviour is verified through the Yoast SEO Premium PR.

Impact check

This PR affects the following parts of the plugin, which may require extra testing:

  • Bulk editor tab navigation (Search ↔ Social) and the existing unsaved-changes modal.
  • The @yoast/bulk-editor data store.

Other environments

  • This PR also affects Shopify.
  • This PR also affects Yoast SEO for Google Docs.

Documentation

  • I have written documentation for this change.

Quality assurance

  • I have tested this code to the best of my abilities.
  • During testing, I had activated all plugins that Yoast SEO provides integrations for.
  • I have added unit tests to verify the code works as intended.
  • If any part of the code is behind a feature flag, my test instructions also cover cases where the feature flag is switched off.
  • I have written this PR in accordance with my team's definition of done.
  • I have checked that the base branch is correctly set.
  • I have run grunt build:images and committed the results, if my PR introduces or edits images or SVGs.

Innovation

  • [] No innovation project is applicable for this PR.

Part of Yoast/reserved-tasks#1297.

Lets an external plugin (Premium AI suggestions) report pending changes via a new externalPendingChanges store flag, so the tab-change guard defers the switch and renders a PENDING_CHANGES_MODAL_SLOT for the plugin to fill with its own confirmation modal.

A self-healing effect completes a deferred switch once its guard clears, so pendingTab can't get stranded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thijsoo thijsoo added innovation Innovative issue. Relating to performance, memory or data-flow. changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog labels Jun 25, 2026
@coveralls

coveralls commented Jun 25, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 0

Coverage decreased (-5.6%) to 45.605%

Details

  • Coverage decreased (-5.6%) from the base build.
  • Patch coverage: 3 uncovered changes across 1 file (12 of 15 lines covered, 80.0%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
packages/js/src/bulk-editor/components/bulk-editor-content.js 8 5 62.5%
Total (3 files) 15 12 80.0%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 60662
Covered Lines: 28986
Line Coverage: 47.78%
Relevant Branches: 11775
Covered Branches: 4049
Branch Coverage: 34.39%
Branches in Coverage %: Yes
Coverage Strength: 6.72 hits per line

💛 - Coveralls

@github-actions

Copy link
Copy Markdown

A merge conflict has been detected for the proposed code changes in this PR. Please resolve the conflict by either rebasing the PR or merging in changes from the base branch.

…into 1297-premium-fe-5-bulk-editor-ai-suggested-pending-changes-alert

# Conflicts:
#	packages/js/src/bulk-editor/components/bulk-editor-content.js
#	packages/js/src/bulk-editor/constants.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog: non-user-facing Needs to be included in the 'Non-userfacing' category in the changelog innovation Innovative issue. Relating to performance, memory or data-flow.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants