Skip to content

Support ActiveAdmin 4 - #60

Open
senid231 wants to merge 9 commits into
masterfrom
activeadmin-v4
Open

senid231 wants to merge 9 commits into
masterfrom
activeadmin-v4

Conversation

@senid231

@senid231 senid231 commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Adds ActiveAdmin 4 support. ActiveAdmin 4 has no jQuery or jQuery UI, so the dialog is a new ES module that opens a Flowbite modal and posts the same params as the v3 dialog (changes[...], collection_selection[], authenticity_token, batch_action). ActiveAdmin 3 keeps its jQuery UI JS and SCSS unchanged; Ruby picks the v4 markup with aa_v4?.

Decisions not visible in the diff:

  • The engine pins the module into ActiveAdmin.importmap. Hosts import it through javascript_modules when ActiveAdmin has it (Add javascript_modules setting to import modules on every page activeadmin/activeadmin#9148), through ActiveAdminTheme.javascripts, or by overriding _html_head. The README covers all three.
  • No CSS file. The modal and sidebar use Tailwind classes with dark: variants, and hosts add the gem to Tailwind content.
  • The module file is not named after the gem, because Propshaft would serve the Sprockets bundle from vendor/assets under that name.
  • mass_update_modal_dialog:before_open/after_open are now bubbling CustomEvents with detail.form.
  • The dummy app needed fixes for Ransack 6 and Rails 8 lazy routes, which also broke master locally.

Release impact: minor. v3 behaviour and assets are unchanged, and the gemspec now allows < 5.0.0.a.

Verified: the full suite passes on AA 3.5.2 (Rails 8.0) and AA 4.0.0.beta23 (Rails 8.1), plus v4-only modal specs.

Ransack 6 raises unless Author allowlists its associations, and Rails 8
draws routes lazily outside CI, so batch actions were missing locally.

Co-Authored-By: Clanker
ActiveAdmin 4 prints a sidebar block result that is not an Arbre element,
and no longer wraps sections in a panel.

Co-Authored-By: Clanker
ActiveAdmin 4 ships neither jQuery nor jQuery UI. The module is pinned into
ActiveAdmin.importmap and posts the same params as the jQuery UI dialog.

Co-Authored-By: Clanker
Co-Authored-By: Clanker
@senid231 senid231 self-assigned this Nov 12, 2026
@senid231
senid231 requested a balanced review from Copilot November 12, 2026 11:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved critical issues can cause AA4/Sprockets import-map rendering failures and duplicate batch-action execution while a POST request is pending.

4 open issues
What changed in this PR

Adds ActiveAdmin 4 support with a Flowbite-based dialog while retaining the existing ActiveAdmin 3 jQuery UI assets.

Changes:

  • Adds an ES module, importmap integration, and version-specific sidebar markup.
  • Documents ActiveAdmin 4 setup and extends the supported dependency range.
  • Updates shared feature specs, adds v4 modal tests, and expands CI coverage.
File Description
tasks/​test.rake Supports a configurable dummy-app path.
spec/​support/​tailwind.rb Compiles Tailwind styles for v4 tests.
spec/​support/​rails_template.rb Configures version-specific dummy-app assets and compatibility fixes.
spec/​support/​dialog.rb Adds shared helpers for v3 and v4 dialogs.
spec/​spec_helper.rb Configures version-specific test setup and route loading.
spec/​records_count_spec.rb Uses shared dropdown selectors.
spec/​records_count_authorization_spec.rb Uses version-aware dialog and flash selectors.
spec/​posts_actions_spec.rb Adapts update and confirmation tests for both versions.
spec/​dialog_v4_spec.rb Tests v4 modal attributes, events, and cancellation.
spec/​confirm_options_spec.rb Adapts confirmation-option tests for both versions.
spec/​authors_actions_spec.rb Adapts action, date-input, and sidebar tests.
README.md Documents v4 installation, styling, and events.
lib/​active_admin_scoped_collection_actions/​resource_extension.rb Adds v4 sidebar markup and button attributes.
lib/​active_admin_scoped_collection_actions/​engine.rb Registers the dialog module with ActiveAdmin.
lib/​active_admin_scoped_collection_actions.rb Adds ActiveAdmin version detection.
gemfiles/​activeadmin_4.0.gemfile Defines the v4 test dependencies.
config/​importmap.rb Pins the new dialog module.
CHANGELOG.md Records ActiveAdmin 4 support.
app/​javascript/​active_admin_scoped_collection_actions/​dialog.js Implements the Flowbite action dialog and submissions.
active_admin_scoped_collection_actions.gemspec Allows ActiveAdmin versions below 5.
.gitignore Ignores test-bundle lockfiles.
.github/​workflows/​ci.yml Adds ActiveAdmin 4 matrix entries.

Review effort: Balanced

Guard against a second submit or a stacked modal, submit an empty value
for nil select options, label the modal by its heading, and add the
module to the Sprockets precompile list.

Co-Authored-By: Clanker
Co-Authored-By: Clanker
Send an enabled but unchecked checkbox as "off", keep the modal open once
the action is sent, focus the modal on open, and have the importmap cache
sweeper watch the gem's JavaScript.

Co-Authored-By: Clanker
Replacing ActiveAdmin's cache sweeper outright drops directories other
engines register through importmap_watches (activeadmin/activeadmin#9153).
Rebuild the sweeper only when that setting is missing.

Co-Authored-By: Clanker

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The modal has accessibility gaps: value controls lack accessible names, keyboard focus can escape to the background, and closing it does not restore focus to the action button.

No open issues 🎉

3 previously missed issues

In code that hasn't changed since last review

Medium severity Value control lacks an accessible name

app/​javascript/​active_admin_scoped_collection_actions/​dialog.js:96

The label's for points to the enable checkbox, so the actual value input/select has no accessible name after it is enabled. Screen-reader users encounter an unnamed text box, date field, select, or second checkbox without knowing which attribute it changes. Please also give the value control an accessible name using the field label.

Medium severity Closing the modal does not restore focus

app/​javascript/​active_admin_scoped_collection_actions/​dialog.js:189

Closing with Cancel or Escape removes the focused control, but neither this handler nor Flowbite restores focus to the action button. Keyboard users lose their place in the page's navigation. Restore focus to the existing button argument after removing the modal.

Medium severity Modal does not trap keyboard focus

app/​javascript/​active_admin_scoped_collection_actions/​dialog.js:263

The initial focus call does not keep keyboard focus inside the modal, and Flowbite does not provide a focus trap. Shift+Tab from the first control or Tab past Cancel/Back can reach the background page while the modal remains open. Trap focus within the visible modal controls across step changes, or make the background inert until the modal closes.

4 resolved since last review

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved accessibility issues leave value controls unnamed for screen readers and lose keyboard focus when navigating Back or closing the dialog.

3 open issues

Review effort: Balanced

throw new Error(`Unsupported input type: {${name}: ${type}}`)
}

input.disabled = true
onHide: () => {
setTimeout(() => {
modal.destroyAndRemoveInstance()
modalEl.remove()
waiting = null
ok.disabled = false
step.remove()
back.replaceWith(cancel)

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