Skip to content

[6.x] Move legacy element action triggers to the Yii2 adapter - #20592

Draft
brianjhanson wants to merge 1 commit into
6.xfrom
chore/element-action-triggers-to-adapter
Draft

brianjhanson wants to merge 1 commit into
6.xfrom
chore/element-action-triggers-to-adapter

Conversation

@brianjhanson

@brianjhanson brianjhanson commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Description

Core element actions no longer write JavaScript. Their getTriggerHtml() overrides only ever served the legacy (jQuery) element index; the Vue index never calls them. The legacy index now builds those triggers itself, from a descriptor the Yii2 adapter adds.

Before                                          After
──────                                          ─────
core ElementAction::getTriggerHtml()            core: getTriggerHtml()/getTriggerId() removed
  └─ HtmlStack::js(<<<JS new Craft.             adapter LegacyElementActions::actionConfig()
       ElementActionTrigger({...}) JS)            └─ legacyTrigger: {handler: 'delete', withDescendants, …}
ElementHelper::actionConfig()                   cpcompat element-index/action-triggers.js
  └─ trigger, triggerId                           └─ handlers.delete(params) → new Craft.ElementActionTrigger
  • Removed the overrides from Delete, DeleteAssets, DeleteForSite, Duplicate, Restore, SetStatus, SuspendUsers and UnsuspendUsers. Core src/ is +1/−341.
  • The adapter binds LegacyElementActions over ElementActions. It adds trigger, triggerId and legacyTrigger to each action's config, and gives repeated actions distinct trigger IDs.
  • craft\base\ElementAction keeps getTriggerId() and getTriggerHtml(), so Craft 5 plugin actions that render their own trigger still work.
  • The SetStatus trigger template moved to the adapter.

Commerce companion: craftcms/commerce#4445

Evidence

  • Before: rg getTriggerHtml src/ matches the interface, the base class and 8 element actions.
    After: no matches.
  • New yii2-adapter/tests-laravel/Element/LegacyElementActionsTest.php:
    serializeActions([Delete])            → legacyTrigger.handler === 'delete'
    serializeActions([Delete, Delete])    → triggerIds '…-actiontrigger', '…-actiontrigger-2'
    action overriding getTriggerHtml()    → uses its own trigger, no legacyTrigger
    handlers in action-triggers.js        === handlers the adapter emits
    
  • Local CI on the branch rebased onto 6.x: Pest 12,545 passed, adapter Pest 1,022 passed, PHPStan (core + adapter), Pint, Rector, vp fmt, lint, typecheck, Vitest unit (2,580) and the legacy bundle build all pass.

Not yet clicked through by hand on a legacy element index.

🤖 Generated with Claude Code

Core element actions no longer write JavaScript for the legacy jQuery
element index. getTriggerHtml() and getTriggerId() are removed from
ElementActionInterface and ElementAction, along with the trigger JS in
Delete, DeleteAssets, Duplicate, DeleteForSite, Restore, SetStatus,
SuspendUsers, and UnsuspendUsers.

The adapter's LegacyElementActions adds triggers back to the action
configs the legacy index receives. Actions that define getTriggerHtml(),
such as Craft 5 plugin actions, still supply their own. The built-in
actions get a legacyTrigger descriptor, which the legacy index turns
into a Craft.ElementActionTrigger using handlers in action-triggers.js.
craft\base\ElementAction keeps both methods for Craft 5 plugins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/ui — open Storybook

No changed components detected in this Storybook.

resources/js — open Storybook

No changed components detected in this Storybook.

Copilot AI 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.

🔵 Needs a closer look

Serialization tests do not exercise the new legacy-index client lifecycle, so repeated Delete actions, asset-folder deletion, and plugin-supplied triggers still require browser verification.

No open issues 🎉

What changed in this PR

This PR separates legacy element-index presentation from core element actions. The Yii2 adapter supplies trigger descriptors and markup, while the legacy JavaScript index creates the triggers.

Changes:

  • Removes legacy trigger methods and JavaScript generation from core element actions.
  • Adds adapter-managed triggers, distinct IDs for repeated built-in actions, and support for plugin-defined triggers.
  • Adds serialization tests and documents the API changes.
File Description
yii2-adapter/​tests-laravel/​Element/​LegacyElementActionsTest.php Tests descriptors, trigger IDs, custom triggers, and handler coverage.
yii2-adapter/​src/​Yii2ServiceProvider.php Registers the adapter’s element-action service.
yii2-adapter/​src/​Mixins/​NestedElementManagerMixin.php Uses adapter serialization for nested-element actions.
yii2-adapter/​src/​Element/​LegacyElementActions.php Supplies legacy markup, descriptors, and trigger IDs.
yii2-adapter/​resources/​templates/​_components/​elementactions/​SetStatus/​trigger.twig Houses the legacy status-trigger template.
yii2-adapter/​legacy/​helpers/​ElementHelper.php Delegates action configuration to the adapter.
yii2-adapter/​legacy/​base/​ElementAction.php Preserves legacy trigger methods for plugin actions.
src/​User/​Actions/​UnsuspendUsers.php Removes embedded unsuspend-trigger JavaScript.
src/​User/​Actions/​SuspendUsers.php Removes embedded suspend-trigger JavaScript.
src/​Element/​ElementHelper.php Removes legacy trigger fields from core configuration.
src/​Element/​Contracts/​ElementActionInterface.php Removes legacy trigger requirements.
src/​Element/​Actions/​SetStatus.php Removes legacy trigger rendering and JavaScript.
src/​Element/​Actions/​Restore.php Removes legacy restore-trigger generation.
src/​Element/​Actions/​ElementAction.php Removes default legacy trigger methods.
src/​Element/​Actions/​Duplicate.php Removes embedded duplication-trigger JavaScript.
src/​Element/​Actions/​DeleteForSite.php Removes embedded site-deletion trigger JavaScript.
src/​Element/​Actions/​Delete.php Removes legacy trigger generation and ID allocation.
src/​Asset/​Actions/​DeleteAssets.php Removes asset-specific trigger JavaScript.
resources/​js/​modules/​element-action-trigger/​element-action-trigger.ts Updates comments describing trigger creation.
resources/​js/​modules/​element-action-trigger/​compat.ts Updates the global-registration comment.
packages/​craftcms-legacy/​cpcompat/​src/​element-index/​BaseElementIndex.js Creates triggers from action descriptors.
packages/​craftcms-legacy/​cpcompat/​src/​element-index/​action-triggers.js Implements built-in legacy trigger behavior.
CHANGELOG.md Documents trigger API removal and adapter support.
CHANGELOG-WIP.md Adds the API change to migration notes.

Review effort: Balanced

This branch has not been deployed

No deployments
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.

2 participants