activeadmin 4.0.0.beta9 → 4.0.0.beta11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f3c2998aa1c2b5375196a1f9ee0284c699e72a7637f9feab724c46ba0701cee
4
- data.tar.gz: 670befa4df9c7d9634320c2735254a420adf7062789ec47ca4bdaa46c8915328
3
+ metadata.gz: df061ca5e8da419454b4e71fac6d1f1a5c0d10ac2bb134a9ed42d1e939605189
4
+ data.tar.gz: 6bf6a2af2771226c400200da710d1b21d91e22415ca724df6f2417c30edd85dc
5
5
  SHA512:
6
- metadata.gz: bc6cab08a78331723344a4307ac5259f30e090e69d6438433697fbf96d43df7a11ca5f5e88d19a3e0c7cf83f833a99d663e74df4f37122b8c1d71375c8c08bea
7
- data.tar.gz: 927876e56533e12df325ab50e86058dce84cb47133924fc92559ce7329b376ef6d7f574ee35517ac4115f43cd49469a5ddc308716c51621fe726ff219895950f
6
+ metadata.gz: d75f067eb76806efc510ea3050a6c3b4394e2e731a01b6e6ba07169c3bdabd4620f338e6646e3558c99f830db2767cf4023492fb02294e9c78853dd4d114f7d0
7
+ data.tar.gz: 194fd87159da440d9d45b81a54edbd52051322f8dab8f09b95762c9883907c48da255a5b67f2af452e2ad8265a859f135f917385ca7431a888aaaf306747fffb
data/README.md CHANGED
@@ -92,7 +92,7 @@ Thanks to [Open Collective][opencollective contributors] and all our Open Collec
92
92
  [tidelift_enterprise]: https://tidelift.com/subscription/pkg/rubygems-activeadmin?utm_source=rubygems-activeadmin&utm_medium=referral&utm_campaign=enterprise
93
93
  [tidelift_support]: https://tidelift.com/subscription/pkg/rubygems-activeadmin?utm_source=rubygems-activeadmin&utm_medium=referral&utm_campaign=github&utm_content=support
94
94
 
95
- [docs]: https://activeadmin.info/0-installation.html
95
+ [docs]: https://activeadmin.info/
96
96
  [wiki]: https://github.com/activeadmin/activeadmin/wiki
97
97
  [stackoverflow]: https://stackoverflow.com/questions/tagged/activeadmin
98
98
  [contributing]: https://github.com/activeadmin/activeadmin/blob/master/CONTRIBUTING.md
data/UPGRADING.md CHANGED
@@ -8,14 +8,14 @@ ActiveAdmin v4 uses TailwindCSS. It has **mobile web, dark mode and RTL support*
8
8
 
9
9
  These instructions assume the `cssbundling-rails` and `importmap-rails` gems are already installed and you have run their install commands in your app. If you haven't done so, please do before continuing.
10
10
 
11
- Update your `Gemfile` with `gem "activeadmin", "4.0.0.beta3"` and then run `gem install activeadmin --pre`.
11
+ Update your `Gemfile` with `gem "activeadmin", "4.0.0.beta11"` and then run `gem install activeadmin --pre`.
12
12
 
13
13
  Now, run `rails generate active_admin:assets` to replace the old assets with the new files.
14
14
 
15
15
  Then add the npm package and update the `build:css` script.
16
16
 
17
17
  ```
18
- yarn add @activeadmin/activeadmin@4.0.0-beta3
18
+ yarn add @activeadmin/activeadmin@4.0.0-beta11
19
19
  npm pkg set scripts.build:css="tailwindcss -i ./app/assets/stylesheets/active_admin.css -o ./app/assets/builds/active_admin.css --minify -c tailwind-active_admin.config.js"
20
20
  ```
21
21
 
@@ -61,7 +61,7 @@ module ActiveAdmin
61
61
  def self.wrap!(parent, name)
62
62
  ::Class.new parent do
63
63
  delegate :reorder, :page, :current_page, :total_pages, :limit_value,
64
- :total_count, :total_pages, :offset, :to_key, :group_values,
64
+ :total_count, :offset, :to_key, :group_values,
65
65
  :except, :find_each, :ransack, to: :object
66
66
 
67
67
  define_singleton_method(:name) { name }
@@ -108,8 +108,8 @@ module ActiveAdmin
108
108
  when TrueClass, FalseClass
109
109
  true
110
110
  else
111
- if resource.class.respond_to? :columns_hash
112
- column = resource.class.columns_hash[attr.to_s] and column.type == :boolean
111
+ if resource.class.respond_to? :attribute_types
112
+ resource.class.attribute_types[attr.to_s].is_a?(ActiveModel::Type::Boolean)
113
113
  end
114
114
  end
115
115
  end
@@ -14,7 +14,7 @@ const batchActionClick = function(event) {
14
14
  batchAction.value = this.dataset.action
15
15
  }
16
16
 
17
- if (!event.target.dataset.confirm) { submitForm() }
17
+ if (!event.target.dataset.confirm && !event.target.dataset.modalTarget) { submitForm() }
18
18
  }
19
19
 
20
20
  const batchActionConfirmComplete = function(event) {
data/config/importmap.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  pin "flowbite", preload: true # downloaded from https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.2.1/flowbite.min.js
3
- pin "@rails/ujs", to: "rails_ujs_esm.js", preload: true # downloaded from https://cdn.jsdelivr.net/npm/@rails/ujs@7.1.2/+esm
3
+ pin "@rails/ujs", to: "rails_ujs_esm.js", preload: true # downloaded from https://cdn.jsdelivr.net/npm/@rails/ujs@7.1.400/+esm
4
4
  pin "active_admin", to: "active_admin.js", preload: true
5
5
  pin_all_from File.expand_path("../app/javascript/active_admin", __dir__), under: "active_admin", preload: true
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ module ActiveAdmin
3
+ class AsyncCount
4
+ class NotSupportedError < RuntimeError; end
5
+
6
+ def initialize(collection)
7
+ raise NotSupportedError, "#{collection.inspect} does not support :async_count" unless collection.respond_to?(:async_count)
8
+
9
+ @collection = collection.except(:select, :order)
10
+ @promise = @collection.async_count
11
+ end
12
+
13
+ def count
14
+ value = @promise.value
15
+ # value.value due to Rails bug https://github.com/rails/rails/issues/50776
16
+ value.respond_to?(:value) ? value.value : value
17
+ end
18
+
19
+ alias size count
20
+
21
+ delegate :except, :group_values, :length, :limit_value, to: :@collection
22
+ end
23
+ end
@@ -14,6 +14,12 @@ module ActiveAdmin
14
14
  # Scope.new('Published', :public)
15
15
  # # => Scope with name 'Published' and scope method :public
16
16
  #
17
+ # Scope.new(:published, show_count: :async)
18
+ # # => Scope with name 'Published' that queries its count asynchronously
19
+ #
20
+ # Scope.new(:published, show_count: false)
21
+ # # => Scope with name 'Published' that does not display a count
22
+ #
17
23
  # Scope.new 'Published', :public, if: proc { current_admin_user.can? :manage, resource_class } do |articles|
18
24
  # articles.where published: true
19
25
  # end
@@ -61,5 +67,9 @@ module ActiveAdmin
61
67
  end
62
68
  end
63
69
 
70
+ def async_count?
71
+ @show_count == :async
72
+ end
73
+
64
74
  end
65
75
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ActiveAdmin
3
- VERSION = "4.0.0.beta9"
3
+ VERSION = "4.0.0.beta11"
4
4
  end
@@ -131,12 +131,24 @@ module ActiveAdmin
131
131
  html_options[:class] ||= "inputs"
132
132
  legend = args.shift if args.first.is_a?(::String)
133
133
  legend = html_options.delete(:name) if html_options.key?(:name)
134
- legend_tag = legend ? "<legend class=\"fieldset-title\">#{ERB::Util.html_escape(legend)}</legend>" : ""
135
- fieldset_attrs = html_options.map { |k, v| %Q{#{k}="#{v}"} }.join(" ")
134
+ legend_tag = legend ? helpers.tag.legend(legend, class: "fieldset-title") : ""
135
+ fieldset_attrs = tag_attributes html_options
136
136
  @opening_tag = "<fieldset #{fieldset_attrs}>#{legend_tag}<ol>"
137
137
  @closing_tag = "</ol></fieldset>"
138
138
  super(*(args << html_options), &block)
139
139
  end
140
+
141
+ private
142
+
143
+ def tag_attributes(html_options)
144
+ if Rails::VERSION::MAJOR <= 6
145
+ # Reimplement tag.attributes to backport support for Rails 6.1.
146
+ # TODO: this can be removed when support for Rails 6.x is dropped
147
+ helpers.tag.tag_options(html_options.to_h).to_s.strip.html_safe
148
+ else
149
+ helpers.tag.attributes html_options
150
+ end
151
+ end
140
152
  end
141
153
 
142
154
  class SemanticActionsProxy < FormtasticProxy
@@ -23,6 +23,7 @@ module ActiveAdmin
23
23
 
24
24
  def row(*args, &block)
25
25
  title = args[0]
26
+ data = args[1] || args[0]
26
27
  options = args.extract_options!
27
28
  options["data-row"] = title.to_s.parameterize(separator: "_") if title.present?
28
29
 
@@ -32,7 +33,7 @@ module ActiveAdmin
32
33
  end
33
34
  @collection.each do |record|
34
35
  td do
35
- content_for(record, block || title)
36
+ content_for(record, block || data)
36
37
  end
37
38
  end
38
39
  end
@@ -102,7 +102,10 @@ module ActiveAdmin
102
102
  # you pass in the :total_pages option. We issue a query to determine
103
103
  # if there is another page or not, but the limit/offset make this
104
104
  # query fast.
105
- offset = @collection.offset(@collection.current_page * @collection.limit_value).limit(1).count
105
+ offset_scope = @collection.offset(@collection.current_page * @collection.limit_value)
106
+ # Support array collections. Kaminari::PaginatableArray does not respond to except
107
+ offset_scope = offset_scope.except(:select, :order) if offset_scope.respond_to?(:except)
108
+ offset = offset_scope.limit(1).count
106
109
  options[:total_pages] = @collection.current_page + offset
107
110
  options[:right] = 0
108
111
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "active_admin/async_count"
2
3
  require "active_admin/view_helpers/method_or_proc_helper"
3
4
 
4
5
  module ActiveAdmin
@@ -15,10 +16,12 @@ module ActiveAdmin
15
16
  def build(scopes, options = {})
16
17
  super({ role: "toolbar" })
17
18
  add_class "scopes"
19
+ prepare_async_counts(scopes, options)
20
+
18
21
  scopes.group_by(&:group).each do |group, group_scopes|
19
22
  div class: "index-button-group", role: "group", data: { "group": group_name(group) } do
20
23
  group_scopes.each do |scope|
21
- build_scope(scope, options) if call_method_or_exec_proc(scope.display_if_block)
24
+ build_scope(scope, options) if display_scope?(scope)
22
25
  end
23
26
 
24
27
  nil
@@ -55,12 +58,31 @@ module ActiveAdmin
55
58
 
56
59
  # Return the count for the scope passed in.
57
60
  def get_scope_count(scope)
58
- collection_size(scope_chain(scope, collection_before_scope))
61
+ chained = @async_counts[scope] || scope_chain(scope, collection_before_scope)
62
+
63
+ collection_size(chained)
59
64
  end
60
65
 
61
66
  def group_name(group)
62
67
  group.present? ? group : "default"
63
68
  end
69
+
70
+ private
71
+
72
+ def display_scope?(scope)
73
+ call_method_or_exec_proc(scope.display_if_block)
74
+ end
75
+
76
+ def prepare_async_counts(scopes, options)
77
+ @async_counts = if options[:scope_count]
78
+ scopes
79
+ .select(&:async_count?)
80
+ .select { |scope| display_scope?(scope) }
81
+ .index_with { |scope| AsyncCount.new(scope_chain(scope, collection_before_scope)) }
82
+ else
83
+ {}
84
+ end
85
+ end
64
86
  end
65
87
  end
66
88
  end
@@ -16,6 +16,9 @@ module ActiveAdmin
16
16
  @resource_class ||= @collection.klass if @collection.respond_to? :klass
17
17
 
18
18
  @columns = []
19
+ @tbody_html = options.delete(:tbody_html)
20
+ @row_html = options.delete(:row_html)
21
+ # To be deprecated, please use row_html instead.
19
22
  @row_class = options.delete(:row_class)
20
23
 
21
24
  build_table
@@ -91,10 +94,12 @@ module ActiveAdmin
91
94
  end
92
95
 
93
96
  def build_table_body
94
- @tbody = tbody do
97
+ @tbody = tbody **(@tbody_html || {}) do
95
98
  # Build enough rows for our collection
96
99
  @collection.each do |elem|
97
- tr(id: dom_id_for(elem), class: @row_class&.call(elem))
100
+ html_options = @row_html&.call(elem) || {}
101
+ html_options.reverse_merge!(class: @row_class&.call(elem))
102
+ tr(id: dom_id_for(elem), **html_options)
98
103
  end
99
104
  end
100
105
  end
@@ -196,17 +196,25 @@ module ActiveAdmin
196
196
  # end
197
197
  # ```
198
198
  #
199
- # ## Custom row class
199
+ # ## Custom tbody HTML attributes
200
200
  #
201
- # In order to add special class to table rows pass the proc object as a `:row_class` option
202
- # of the `index` method.
201
+ # In order to add HTML attributes to the tbody use the `:tbody_html` option.
203
202
  #
204
203
  # ```ruby
205
- # index row_class: ->elem { 'active' if elem.active? } do
204
+ # index tbody_html: { class: "my-class", data: { controller: 'stimulus-controller' } } do
206
205
  # # columns
207
206
  # end
208
207
  # ```
209
208
  #
209
+ # ## Custom row HTML attributes
210
+ #
211
+ # In order to add HTML attributes to table rows, use a proc object in the `:row_html` option.
212
+ #
213
+ # ```ruby
214
+ # index row_html: ->elem { { class: ('active' if elem.active?), data: { 'element-id' => elem.id } } } do
215
+ # # columns
216
+ # end
217
+ # ```
210
218
  class IndexAsTable < ActiveAdmin::Component
211
219
  def build(page_presenter, collection)
212
220
  add_class "index-as-table"
@@ -215,6 +223,9 @@ module ActiveAdmin
215
223
  sortable: true,
216
224
  i18n: active_admin_config.resource_class,
217
225
  paginator: page_presenter[:paginator] != false,
226
+ tbody_html: page_presenter[:tbody_html],
227
+ row_html: page_presenter[:row_html],
228
+ # To be deprecated, please use row_html instead.
218
229
  row_class: page_presenter[:row_class]
219
230
  }
220
231
 
@@ -9,6 +9,7 @@ module.exports = {
9
9
  './app/admin/**/*.{arb,erb,html,rb}',
10
10
  './app/views/active_admin/**/*.{arb,erb,html,rb}',
11
11
  './app/views/admin/**/*.{arb,erb,html,rb}',
12
+ './app/views/layouts/active_admin*.{erb,html}',
12
13
  './app/javascript/**/*.js'
13
14
  ],
14
15
  darkMode: "selector",
data/plugin.js CHANGED
@@ -312,7 +312,7 @@ module.exports = plugin(
312
312
  '[type=radio]': {
313
313
  '@apply w-4 h-4 border-gray-300 focus:ring-2 focus:ring-blue-300 dark:focus:ring-blue-600 dark:focus:bg-blue-600 dark:bg-gray-700 dark:border-gray-600': {}
314
314
  },
315
- [['[type=date]', '[type=email]', '[type=number]', '[type=password]', '[type=tel]', '[type=text]', '[type=time]', '[type=url]', 'select', 'textarea']]: {
315
+ [['[type=datetime-local]', '[type=month]', '[type=week]', '[type=search]', '[type=date]', '[type=email]', '[type=number]', '[type=password]', '[type=tel]', '[type=text]', '[type=time]', '[type=url]', 'select', 'textarea']]: {
316
316
  '@apply bg-gray-50 border border-gray-300 text-gray-900 rounded-md focus:ring-blue-500 focus:border-blue-500 w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500': {}
317
317
  },
318
318
  'a': {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeadmin
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta9
4
+ version: 4.0.0.beta11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Maresh
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2024-08-04 00:00:00.000000000 Z
18
+ date: 2024-08-31 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: arbre
@@ -263,6 +263,7 @@ files:
263
263
  - lib/active_admin.rb
264
264
  - lib/active_admin/application.rb
265
265
  - lib/active_admin/application_settings.rb
266
+ - lib/active_admin/async_count.rb
266
267
  - lib/active_admin/authorization_adapter.rb
267
268
  - lib/active_admin/batch_actions.rb
268
269
  - lib/active_admin/batch_actions/controller.rb
@@ -383,7 +384,7 @@ licenses:
383
384
  - MIT
384
385
  metadata:
385
386
  bug_tracker_uri: https://github.com/activeadmin/activeadmin/issues
386
- changelog_uri: https://github.com/activeadmin/activeadmin/blob/master/CHANGELOG.md
387
+ changelog_uri: https://github.com/activeadmin/activeadmin/releases
387
388
  documentation_uri: https://activeadmin.info
388
389
  homepage_uri: https://activeadmin.info
389
390
  mailing_list_uri: https://groups.google.com/group/activeadmin