Skip to content

Support ActiveAdmin 4 with native datetime-local inputs - #97

Open
senid231 wants to merge 6 commits into
activeadmin-plugins:masterfrom
senid231:activeadmin-v4
Open

senid231 wants to merge 6 commits into
activeadmin-plugins:masterfrom
senid231: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 Sprockets, so on v4 the date_time_picker input and the date_time_range filter render native datetime-local fields (date for a date column) instead of the xdsoft picker. ActiveAdmin 3 behaviour and assets are unchanged.

Decisions not visible in the diff:

  • No JS or CSS on v4. ActiveAdmin 4 already styles native date inputs, including dark mode, so hosts install nothing.
  • The v4 filter copies ActiveAdmin 4's DateRangeInput markup (.filters-form-input-group) and adds back the filter_date_time_range wrapper class so active_admin_date_range_preset can find the pair.
  • Values are ISO (YYYY-MM-DDTHH:MM). A Ransack formatter swaps the T for a space, but only for untyped ransackers, which compare as strings.
  • min_date/max_date/step map to min/max/step. Other xdsoft options are ignored on v4, as the README now says.
  • New data-datetimepicker-* hooks on inputs and the range wrapper, on v3 and v4.
  • Gemspec widened to < 5.0.0.a, so ActiveAdmin 5 prereleases stay out. Minor release: nothing changes for v3 hosts.

Verified locally: full suite green on AA 3.5 and AA 4.0.0.beta23 (Rails 8.0, plus 8.1 on v4). CI matrix gains a 4.0.0.beta23 column.

AA=4.0.0.beta23 swaps Sprockets for Propshaft and importmap-rails, and the
test app is built per ActiveAdmin major. The xdsoft feature specs are tagged
aa: 3 since ActiveAdmin 4 pages load no jQuery.

Co-Authored-By: Clanker
ActiveAdmin 4 has no jQuery, and its date range filter renders date-only
fields. The form input and the range filter now emit datetime-local fields
with ISO values; a Ransack formatter turns the ISO "T" into a space for
ransackers without a type, which compare as strings.

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 10:41

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

The datetime-local max_date fallback uses midnight, incorrectly rejecting later times on the intended inclusive final day, and the spec currently expects that incorrect boundary.

1 open issue
What changed in this PR

Adds ActiveAdmin 4 support through native date and datetime controls, while retaining the existing XDSoft picker for ActiveAdmin 3.

Changes:

  • Adds native input rendering, option mapping, ISO-value handling, and shared data hooks.
  • Separates test-app setup and feature coverage by ActiveAdmin version.
  • Expands supported dependencies and CI coverage, and documents v4 behavior.
File Description
tasks/​test.rake Supports a configurable test-app path.
spec/​support/​rails_template.rb Adapts asset setup for v4 and removes generated specs.
spec/​spec_helper.rb Separates test apps and selects version-specific specs.
spec/​native_inputs_spec.rb Tests native forms, filters, attributes, and browser values.
spec/​filter_form_spec.rb Limits XDSoft filter tests to v3.
spec/​edit_form_spec.rb Limits XDSoft form tests to v3.
spec/​data_hooks_spec.rb Tests shared input and range hooks.
README.md Documents v4 installation and native-input behavior.
lib/​active_admin_datetimepicker/​inputs/​filters/​date_time_range_input.rb Adds native range markup and data hooks.
lib/​active_admin_datetimepicker/​base.rb Formats native values and maps picker options.
lib/​active_admin_datetimepicker.rb Adds ActiveAdmin version detection.
Gemfile Selects asset dependencies by ActiveAdmin version.
config/​initializers/​active_admin_datetimepicker.rb Normalizes ISO strings for Ransack predicates.
active_admin_datetimepicker.gemspec Allows ActiveAdmin 4 and updates the description.
.github/​workflows/​ci.yml Adds ActiveAdmin 4 beta coverage.

Review effort: Balanced

Comment thread lib/active_admin_datetimepicker/base.rb Resolved
XDSoft's maxDate allows the whole last day; midnight blocked every later
time. Time options now render in the app's zone, and the README notes that
the browser enforces min, max and step on submit.

Co-Authored-By: Clanker
Co-Authored-By: Clanker
Stored strings that are not ISO no longer render blank and get wiped on
save, and a Time minDate starts at midnight like xdsoft's.

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

Combined date and datetime limits can discard stricter bounds, while offset-bearing string limits are not normalized to the application time zone, causing incorrect browser validation.

No open issues 🎉

2 previously missed issues

In code that hasn't changed since last review

Medium severity Combine date and datetime limits using the stricter bound

lib/​active_admin_datetimepicker/​base.rb:94

When both date-level and datetime-level limits are configured, || discards the date-level limit even if it is stricter. For example, min_date: '2024-01-20' with min_date_time: '2024-01-10 12:00' allows January 15 despite the date restriction; maximum limits have the same issue. Preserve both constraints by taking the later minimum and the earlier maximum.

Medium severity Normalize offset-bearing limit strings to the application time zone

lib/​active_admin_datetimepicker/​base.rb:119

Offset-bearing strings lose their offset without being converted to the application zone: in a UTC app, min_date_time: '2024-01-20T13:00:00+01:00' renders min="2024-01-20T13:00" instead of 12:00, unlike an equivalent Time/DateTime limit. This causes browser validation to reject valid times or accept times beyond a maximum. Parse strings in Time.zone so explicit offsets are normalized while offsetless values remain local wall times.

1 resolved since last review

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