rails_admin 3.1.3 → 3.2.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +27 -13
  3. data/README.md +2 -2
  4. data/app/assets/javascripts/rails_admin/application.js.erb +3 -2
  5. data/app/assets/stylesheets/rails_admin/application.scss.erb +1 -1
  6. data/app/controllers/rails_admin/main_controller.rb +5 -1
  7. data/app/helpers/rails_admin/main_helper.rb +1 -1
  8. data/app/views/layouts/rails_admin/_head.html.erb +7 -5
  9. data/app/views/rails_admin/main/_form_boolean.html.erb +2 -2
  10. data/app/views/rails_admin/main/_form_filtering_multiselect.html.erb +1 -0
  11. data/app/views/rails_admin/main/_form_filtering_select.html.erb +2 -1
  12. data/app/views/rails_admin/main/_form_nested_many.html.erb +1 -1
  13. data/app/views/rails_admin/main/_form_nested_one.html.erb +1 -1
  14. data/app/views/rails_admin/main/delete.html.erb +1 -1
  15. data/app/views/rails_admin/main/index.html.erb +2 -2
  16. data/lib/generators/rails_admin/importmap_formatter.rb +1 -1
  17. data/lib/generators/rails_admin/install_generator.rb +13 -1
  18. data/lib/generators/rails_admin/templates/rails_admin.vite.js +2 -0
  19. data/lib/rails_admin/abstract_model.rb +8 -0
  20. data/lib/rails_admin/adapters/active_record/association.rb +1 -1
  21. data/lib/rails_admin/adapters/active_record/object_extension.rb +0 -18
  22. data/lib/rails_admin/adapters/active_record.rb +17 -3
  23. data/lib/rails_admin/adapters/mongoid/association.rb +1 -1
  24. data/lib/rails_admin/adapters/mongoid/object_extension.rb +0 -5
  25. data/lib/rails_admin/adapters/mongoid.rb +6 -3
  26. data/lib/rails_admin/config/fields/association.rb +24 -1
  27. data/lib/rails_admin/config/fields/base.rb +4 -4
  28. data/lib/rails_admin/config/fields/types/active_storage.rb +8 -0
  29. data/lib/rails_admin/config/fields/types/has_one_association.rb +11 -0
  30. data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +9 -1
  31. data/lib/rails_admin/support/datetime.rb +1 -0
  32. data/lib/rails_admin/version.rb +3 -3
  33. data/package.json +1 -1
  34. data/src/rails_admin/abstract-select.js +30 -0
  35. data/src/rails_admin/base.js +4 -1
  36. data/src/rails_admin/filtering-multiselect.js +2 -4
  37. data/src/rails_admin/filtering-select.js +1 -4
  38. metadata +36 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03f798619ca0b106577088ff39d25d4103d7096198ff66244f4381023033398b
4
- data.tar.gz: d3bae813acd97182810f9c6ef09fc295888d706810adc314e7992854f7679d84
3
+ metadata.gz: 6ad121e2654221b302244d3792229d2f7ef62e95ff35777196f8f885b945c475
4
+ data.tar.gz: 5f800d3097c56282ed4ec366bf55a2cb839f5bfa481567c16dcdf81684b02ad1
5
5
  SHA512:
6
- metadata.gz: 5ee60d19acc72d93e8b14c7e568ff924ea54558f9de807845cbd278230dc852d119c332b9866b673aea0757cb3f380d6c5abd09af4c71119626cf47c4cd67e6f
7
- data.tar.gz: 74de744e2e07902613ebc9be3975ff6d68aaa7b4e4d38b2b7c0e59b30a5e3c3313331208f911a73419ec6551f98e1e7b2ad67976cbc7a0887f547444436e5ffb
6
+ metadata.gz: e8f2148f02b5b35e9f7f2ae6a8d635b2f10e9fa99370baa0f78d7bc0805880c6d02097b43b928f0abdcf123294910713e68ab87bc0be2c708d436b3eb425ce3c
7
+ data.tar.gz: d708dc50f78bbe22015721d49213d6991048022d4c6773f6168412ad025cb1a8125579bd9daabb20921f2c12bf8c8a846cdd914aa8fefdb8967e0ec8ec028008
data/Gemfile CHANGED
@@ -3,20 +3,14 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gem 'appraisal', '>= 2.0'
6
- gem 'devise'
6
+ gem 'devise', '~> 4.7'
7
7
  gem 'net-smtp', require: false
8
8
  gem 'rails'
9
+ gem 'sassc-rails', '~> 2.1'
10
+ gem 'turbo-rails'
11
+ gem 'vite_rails', require: false
9
12
  gem 'webpacker', require: false
10
- gem 'webrick', '~> 1.7'
11
-
12
- group :active_record do
13
- gem 'paper_trail'
14
-
15
- platforms :ruby, :mswin, :mingw, :x64_mingw do
16
- gem 'mysql2', '>= 0.3.14'
17
- gem 'sqlite3', '~> 1.3'
18
- end
19
- end
13
+ gem 'webrick'
20
14
 
21
15
  group :development, :test do
22
16
  gem 'pry', '>= 0.9'
@@ -25,21 +19,23 @@ end
25
19
  group :test do
26
20
  gem 'cancancan', '~> 3.0'
27
21
  gem 'carrierwave', ['>= 2.0.0.rc', '< 3']
28
- gem 'cuprite'
22
+ gem 'cuprite', '!= 0.15.1'
29
23
  gem 'database_cleaner-active_record', '>= 2.0', require: false
30
24
  gem 'database_cleaner-mongoid', '>= 2.0', require: false
31
25
  gem 'dragonfly', '~> 1.0'
32
26
  gem 'factory_bot', '>= 4.2', '!= 6.4.5'
33
27
  gem 'generator_spec', '>= 0.8'
28
+ gem 'kt-paperclip'
34
29
  gem 'launchy', '>= 2.2'
35
30
  gem 'mini_magick', '>= 3.4'
36
31
  gem 'pundit'
37
32
  gem 'rack-cache', require: 'rack/cache'
38
33
  gem 'rspec-expectations', '!= 3.8.3'
39
- gem 'rspec-rails', '>= 2.14'
34
+ gem 'rspec-rails', '>= 4.0.0.beta2'
40
35
  gem 'rspec-retry'
41
36
  gem 'rubocop', ['~> 1.20', '!= 1.22.2'], require: false
42
37
  gem 'rubocop-performance', require: false
38
+ gem 'shrine', '~> 3.0'
43
39
  gem 'simplecov', '>= 0.9', require: false
44
40
  gem 'simplecov-lcov', require: false
45
41
  gem 'timecop', '>= 0.5'
@@ -48,4 +44,22 @@ group :test do
48
44
  gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
49
45
  end
50
46
 
47
+ group :active_record do
48
+ gem 'paper_trail', '>= 12.0'
49
+
50
+ platforms :ruby, :mswin, :mingw, :x64_mingw do
51
+ gem 'mysql2', '>= 0.3.14'
52
+ gem 'pg', '>= 1.0.0'
53
+ gem 'sqlite3', '~> 1.3'
54
+ end
55
+ end
56
+
57
+ group :mongoid do
58
+ gem 'cancancan-mongoid'
59
+ gem 'carrierwave-mongoid', '>= 0.6.3', require: 'carrierwave/mongoid'
60
+ gem 'kaminari-mongoid'
61
+ gem 'mongoid-paperclip', '>= 0.0.8', require: 'mongoid_paperclip'
62
+ gem 'shrine-mongoid', '~> 1.0'
63
+ end
64
+
51
65
  gemspec
data/README.md CHANGED
@@ -19,8 +19,8 @@ RailsAdmin is a Rails engine that provides an easy-to-use interface for managing
19
19
  - Check out [the docs][docs].
20
20
  - Try the [live demo][demo]. ([Source code][dummy_app])
21
21
 
22
- [demo]: http://rails-admin-tb.herokuapp.com/
23
- [dummy_app]: https://github.com/bbenezech/dummy_app
22
+ [demo]: https://rails-admin.fly.dev/admin/
23
+ [dummy_app]: https://github.com/railsadminteam/rails_admin/tree/master/spec/dummy_app
24
24
  [docs]: https://github.com/railsadminteam/rails_admin/wiki
25
25
 
26
26
  ## Features
@@ -9,6 +9,7 @@
9
9
  //= require 'rails_admin/popper'
10
10
  //= require 'rails_admin/bootstrap'
11
11
 
12
+ //= require 'rails_admin/abstract-select'
12
13
  //= require 'rails_admin/filter-box'
13
14
  //= require 'rails_admin/filtering-multiselect'
14
15
  //= require 'rails_admin/filtering-select'
@@ -20,10 +21,10 @@
20
21
  //= require 'rails_admin/ui'
21
22
  //= require 'rails_admin/custom/ui'
22
23
 
23
- <% if defined?(ActiveStorage) %>
24
+ <% if defined?(ActiveStorage::Engine) %>
24
25
  //= require activestorage
25
26
  <% end %>
26
- <% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %>
27
+ <% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %>
27
28
  //= require trix
28
29
  //= require actiontext
29
30
  <% end %>
@@ -30,6 +30,6 @@
30
30
  @import "rails_admin/styles/base/theming";
31
31
  @import "rails_admin/custom/theming";
32
32
 
33
- <% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %>
33
+ <% if defined?(ActionText::Engine) && Rails.gem_version >= Gem::Version.new('7.0') %>
34
34
  @import "trix";
35
35
  <% end %>
@@ -56,7 +56,11 @@ module RailsAdmin
56
56
  end
57
57
 
58
58
  def back_or_index
59
- params[:return_to].presence && params[:return_to].include?(request.host) && (params[:return_to] != request.fullpath) ? params[:return_to] : index_path
59
+ allowed_return_to?(params[:return_to].to_s) ? params[:return_to] : index_path
60
+ end
61
+
62
+ def allowed_return_to?(url)
63
+ url != request.fullpath && url.start_with?(request.base_url, '/') && !url.start_with?('//')
60
64
  end
61
65
 
62
66
  def get_sort_hash(model_config)
@@ -45,7 +45,7 @@ module RailsAdmin
45
45
  filter_for_field = duplet[1]
46
46
  filter_name = filter_for_field.keys.first
47
47
  filter_hash = filter_for_field.values.first
48
- unless (field = filterable_fields.find { |f| f.name == filter_name.to_sym })
48
+ unless (field = filterable_fields.find { |f| f.name == filter_name.to_sym }&.with({view: self}))
49
49
  raise "#{filter_name} is not currently filterable; filterable fields are #{filterable_fields.map(&:name).join(', ')}"
50
50
  end
51
51
 
@@ -1,7 +1,7 @@
1
- <meta content="IE=edge" http-equiv="X-UA-Compatible"/>
2
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
3
- <meta content="width=device-width, initial-scale=1" name="viewport; charset=utf-8"/>
4
- <meta content="NONE,NOARCHIVE" name="robots"/>
1
+ <meta content="IE=edge" http-equiv="X-UA-Compatible">
2
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
3
+ <meta content="width=device-width, initial-scale=1" name="viewport; charset=utf-8">
4
+ <meta content="NONE,NOARCHIVE" name="robots">
5
5
  <%= csrf_meta_tag %>
6
6
  <% case RailsAdmin::config.asset_source
7
7
  when :webpacker %>
@@ -12,6 +12,8 @@
12
12
  <%= stylesheet_link_tag "rails_admin/application.css", media: :all, data: {'turbo-track': 'reload'} %>
13
13
  <%= javascript_include_tag "rails_admin/application.js", defer: true, data: {'turbo-track': 'reload'} %>
14
14
  <% end %>
15
+ <% when :vite %>
16
+ <%= vite_javascript_tag "rails_admin", defer: true, data: {'turbo-track': 'reload'} %>
15
17
  <% when :webpack %>
16
18
  <%= stylesheet_link_tag "rails_admin.css", media: :all, data: {'turbo-track': 'reload'} %>
17
19
  <%= javascript_include_tag "rails_admin.js", defer: true, data: {'turbo-track': 'reload'} %>
@@ -26,4 +28,4 @@
26
28
  <%= javascript_import_module_tag 'rails_admin' %>
27
29
  <% else
28
30
  raise "Unknown asset_source: #{RailsAdmin::config.asset_source}"
29
- end %>
31
+ end %>
@@ -2,9 +2,9 @@
2
2
  <div class="btn-group" role="group">
3
3
  <% {'1': [true, 'btn-outline-success'], '0': [false, 'btn-outline-danger'], '': [nil, 'btn-outline-secondary']}.each do |text, (value, btn_class)| %>
4
4
  <%= form.radio_button field.method_name, text, field.html_attributes.reverse_merge({ checked: field.form_value == value, required: field.required, class: 'btn-check' }) %>
5
- <label for="<%= form.object_name %>_<%= field.method_name %>_<%= text %>" class="<%= field.css_classes[value] %> btn <%= btn_class %>">
5
+ <%= form.label "#{field.method_name}_#{text}", class: "#{field.css_classes[value]} btn #{btn_class}" do %>
6
6
  <%= field.labels[value].html_safe %>
7
- </label>
7
+ <% end %>
8
8
  <% end %>
9
9
  </div>
10
10
  <% else %>
@@ -20,6 +20,7 @@
20
20
  xhr: xhr,
21
21
  :'edit-url' => (field.inline_edit && authorized?(:edit, config.abstract_model) ? edit_path(model_name: config.abstract_model.to_param, id: '__ID__') : ''),
22
22
  remote_source: index_path(config.abstract_model, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, associated_collection: field.name, current_action: current_action, compact: true),
23
+ scopeBy: field.dynamic_scope_relationships,
23
24
  sortable: !!field.orderable,
24
25
  removable: !!field.removable,
25
26
  cacheAll: !!field.associated_collection_cache_all,
@@ -12,7 +12,8 @@
12
12
 
13
13
  js_data = {
14
14
  xhr: xhr,
15
- remote_source: index_path(config.abstract_model.to_param, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, associated_collection: field.name, current_action: current_action, compact: true)
15
+ remote_source: index_path(config.abstract_model.to_param, source_object_id: form.object.id, source_abstract_model: source_abstract_model.to_param, associated_collection: field.name, current_action: current_action, compact: true),
16
+ scopeBy: field.dynamic_scope_relationships
16
17
  }
17
18
  %>
18
19
 
@@ -3,7 +3,7 @@
3
3
  <a class="<%= (field.active? ? 'active' : '') %> btn btn-info toggler" data-bs-target="<%= form.jquery_namespace(field) %> .collapse" data-bs-toggle="collapse" role="button">
4
4
  <i class="fas"></i>
5
5
  </a>
6
- <% unless field.nested_form[:update_only] || !field.inline_add %>
6
+ <% if field.inline_add %>
7
7
  <%= form.link_to_add "<i class=\"fas fa-plus\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".html_safe, field.name, { class: 'btn btn-info' } %>
8
8
  <% end %>
9
9
  </div>
@@ -4,7 +4,7 @@
4
4
  <a class="<%= (field.active? ? 'active' : '') %> btn btn-info toggler" data-bs-target="<%= form.jquery_namespace(field) %> .collapse" data-bs-toggle="collapse" role="button">
5
5
  <i class="fas"></i>
6
6
  </a>
7
- <% unless field.nested_form[:update_only] || !field.inline_add %>
7
+ <% if field.inline_add %>
8
8
  <%= form.link_to_add "<i class=\"fas fa-plus\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".html_safe, field.name, { class: 'btn btn-info', :'data-add-label' => "<i class=\"fas fa-plus\"></i> #{wording_for(:link, :new, field.associated_model_config.abstract_model)}".gsub("\n", "") } %>
9
9
  <% end %>
10
10
  </div>
@@ -1,6 +1,6 @@
1
1
  <h4>
2
2
  <%= t("admin.form.are_you_sure_you_want_to_delete_the_object", model_name: @abstract_model.pretty_name.downcase) %>
3
- &ldquo;<strong><%= @model_config.with(object: @object).object_label %></strong>&rdquo;
3
+ <q><strong><%= @model_config.with(object: @object).object_label %></strong></q>
4
4
  <%= t("admin.form.all_of_the_following_related_items_will_be_deleted") %>
5
5
  </h4>
6
6
  <ul>
@@ -133,9 +133,9 @@
133
133
  <% end %>
134
134
  <% properties.map{ |property| property.bind(:object, object) }.each do |property| %>
135
135
  <% value = property.pretty_value %>
136
- <td class="<%= [property.sticky? && 'sticky', property.css_class, property.type_css_class].select(&:present?).join(' ') %>" title="<%= value %>">
136
+ <%= content_tag(:td, class: [property.sticky? && 'sticky', property.css_class, property.type_css_class].select(&:present?), title: strip_tags(value.to_s)) do %>
137
137
  <%= value %>
138
- </td>
138
+ <% end %>
139
139
  <% end %>
140
140
  <td class="last links ra-sidescroll-frozen">
141
141
  <ul class="nav d-inline list-inline">
@@ -6,7 +6,7 @@ module RailsAdmin
6
6
  class ImportmapFormatter
7
7
  attr_reader :packager
8
8
 
9
- def initialize(path = 'confing/importmap.rails_admin.rb')
9
+ def initialize(path = 'config/importmap.rails_admin.rb')
10
10
  @packager = Importmap::Packager.new(path)
11
11
  end
12
12
 
@@ -10,7 +10,7 @@ module RailsAdmin
10
10
  include Generators::Utils::InstanceMethods
11
11
 
12
12
  argument :_namespace, type: :string, required: false, desc: 'RailsAdmin url namespace'
13
- class_option :asset, type: :string, required: false, default: nil, desc: 'Asset delivery method [options: webpacker, webpack, sprockets, importmap]'
13
+ class_option :asset, type: :string, required: false, default: nil, desc: 'Asset delivery method [options: webpacker, webpack, sprockets, importmap, vite]'
14
14
  desc 'RailsAdmin installation generator'
15
15
 
16
16
  def install
@@ -33,6 +33,8 @@ module RailsAdmin
33
33
  configure_for_importmap
34
34
  when 'webpacker'
35
35
  configure_for_webpacker5
36
+ when 'vite'
37
+ configure_for_vite
36
38
  when 'sprockets'
37
39
  configure_for_sprockets
38
40
  else
@@ -51,6 +53,8 @@ module RailsAdmin
51
53
  'webpack'
52
54
  elsif Rails.root.join('config/importmap.rb').exist?
53
55
  'importmap'
56
+ elsif defined?(ViteRuby)
57
+ 'vite'
54
58
  else
55
59
  'sprockets'
56
60
  end
@@ -68,6 +72,14 @@ module RailsAdmin
68
72
  add_package_json_field('resolutions', {'rails_admin/@fortawesome/fontawesome-free' => '^5.15.0'})
69
73
  end
70
74
 
75
+ def configure_for_vite
76
+ vite_source_code_dir = ViteRuby.config.source_code_dir
77
+ run "yarn add rails_admin@#{RailsAdmin::Version.js} sass"
78
+ template('rails_admin.vite.js', File.join(vite_source_code_dir, 'entrypoints', 'rails_admin.js'))
79
+ @fa_font_path = '@fortawesome/fontawesome-free/webfonts'
80
+ template('rails_admin.scss.erb', File.join(vite_source_code_dir, 'stylesheets', 'rails_admin.scss'))
81
+ end
82
+
71
83
  def configure_for_webpack
72
84
  run "yarn add rails_admin@#{RailsAdmin::Version.js}"
73
85
  template 'rails_admin.js', 'app/javascript/rails_admin.js'
@@ -0,0 +1,2 @@
1
+ import "~/stylesheets/rails_admin.scss";
2
+ import "rails_admin/src/rails_admin/base";
@@ -60,6 +60,14 @@ module RailsAdmin
60
60
  @model_name.constantize
61
61
  end
62
62
 
63
+ def quoted_table_name
64
+ table_name
65
+ end
66
+
67
+ def quote_column_name(name)
68
+ name
69
+ end
70
+
63
71
  def to_s
64
72
  model.to_s
65
73
  end
@@ -33,7 +33,7 @@ module RailsAdmin
33
33
 
34
34
  def klass
35
35
  if options[:polymorphic]
36
- polymorphic_parents(:active_record, model.name.to_s, name) || []
36
+ polymorphic_parents(:active_record, association.active_record.name.to_s, name) || []
37
37
  else
38
38
  association.klass
39
39
  end
@@ -4,24 +4,6 @@ module RailsAdmin
4
4
  module Adapters
5
5
  module ActiveRecord
6
6
  module ObjectExtension
7
- def self.extended(object)
8
- object.class.reflect_on_all_associations.each do |association|
9
- association = Association.new(association, object.class)
10
- case association.type
11
- when :has_one
12
- object.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
13
- def #{association.name}_id
14
- self.#{association.name}&.id
15
- end
16
-
17
- def #{association.name}_id=(item_id)
18
- self.#{association.name} = (#{association.klass}.find(item_id) rescue nil)
19
- end
20
- RUBY
21
- end
22
- end
23
- end
24
-
25
7
  def assign_attributes(attributes)
26
8
  super if attributes
27
9
  end
@@ -72,6 +72,14 @@ module RailsAdmin
72
72
 
73
73
  delegate :primary_key, :table_name, to: :model, prefix: false
74
74
 
75
+ def quoted_table_name
76
+ model.quoted_table_name
77
+ end
78
+
79
+ def quote_column_name(name)
80
+ model.connection.quote_column_name(name)
81
+ end
82
+
75
83
  def encoding
76
84
  adapter =
77
85
  if ::ActiveRecord::Base.respond_to?(:connection_db_config)
@@ -201,6 +209,8 @@ module RailsAdmin
201
209
  case @type
202
210
  when :boolean
203
211
  boolean_unary_operators
212
+ when :uuid
213
+ uuid_unary_operators
204
214
  when :integer, :decimal, :float
205
215
  numeric_unary_operators
206
216
  else
@@ -230,6 +240,7 @@ module RailsAdmin
230
240
  )
231
241
  end
232
242
  alias_method :numeric_unary_operators, :boolean_unary_operators
243
+ alias_method :uuid_unary_operators, :boolean_unary_operators
233
244
 
234
245
  def range_filter(min, max)
235
246
  if min && max && min == max
@@ -255,9 +266,12 @@ module RailsAdmin
255
266
  end
256
267
 
257
268
  def build_statement_for_boolean
258
- return ["(#{@column} IS NULL OR #{@column} = ?)", false] if %w[false f 0].include?(@value)
259
-
260
- ["(#{@column} = ?)", true] if %w[true t 1].include?(@value)
269
+ case @value
270
+ when 'false', 'f', '0'
271
+ ["(#{@column} IS NULL OR #{@column} = ?)", false]
272
+ when 'true', 't', '1'
273
+ ["(#{@column} = ?)", true]
274
+ end
261
275
  end
262
276
 
263
277
  def column_for_value(value)
@@ -46,7 +46,7 @@ module RailsAdmin
46
46
 
47
47
  def klass
48
48
  if polymorphic? && %i[referenced_in belongs_to].include?(macro)
49
- polymorphic_parents(:mongoid, model.name, name) || []
49
+ polymorphic_parents(:mongoid, association.inverse_class_name, name) || []
50
50
  else
51
51
  association.klass
52
52
  end
@@ -20,11 +20,6 @@ module RailsAdmin
20
20
  send(name)&.save
21
21
  end
22
22
  end
23
- object.instance_eval <<-RUBY, __FILE__, __LINE__ + 1
24
- def #{name}_id=(item_id)
25
- self.#{name} = (#{association.klass}.find(item_id) rescue nil)
26
- end
27
- RUBY
28
23
  end
29
24
  end
30
25
  end
@@ -251,9 +251,12 @@ module RailsAdmin
251
251
  end
252
252
 
253
253
  def build_statement_for_boolean
254
- return {@column => false} if %w[false f 0].include?(@value)
255
-
256
- {@column => true} if %w[true t 1].include?(@value)
254
+ case @value
255
+ when 'false', 'f', '0'
256
+ {@column => false}
257
+ when 'true', 't', '1'
258
+ {@column => true}
259
+ end
257
260
  end
258
261
 
259
262
  def column_for_value(value)
@@ -56,7 +56,30 @@ module RailsAdmin
56
56
  # preload entire associated collection (per associated_collection_scope) on load
57
57
  # Be sure to set limit in associated_collection_scope if set is large
58
58
  register_instance_option :associated_collection_cache_all do
59
- @associated_collection_cache_all ||= (associated_model_config.abstract_model.count < associated_model_limit)
59
+ @associated_collection_cache_all ||= dynamically_scope_by.blank? && (associated_model_config.abstract_model.count < associated_model_limit)
60
+ end
61
+
62
+ # client-side dynamic scoping
63
+ register_instance_option :dynamically_scope_by do
64
+ nil
65
+ end
66
+
67
+ # parses #dynamically_scope_by and returns a Hash in the form of
68
+ # {[form field name in this model]: [field name in the associated model]}
69
+ def dynamic_scope_relationships
70
+ @dynamic_scope_relationships ||=
71
+ Array.wrap(dynamically_scope_by).flat_map do |field|
72
+ field.is_a?(Hash) ? field.to_a : [[field, field]]
73
+ end.map do |field_name, target_name| # rubocop:disable Style/MultilineBlockChain
74
+ field = section.fields.detect { |f| f.name == field_name }
75
+ raise "Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{abstract_model.model_name}'" unless field
76
+
77
+ target_field = associated_model_config.list.fields.detect { |f| f.name == target_name }
78
+ raise "Field '#{field_name}' was given for #dynamically_scope_by but not found in '#{associated_model_config.abstract_model.model_name}'" unless target_field
79
+ raise "Field '#{field_name}' in '#{associated_model_config.abstract_model.model_name}' can't be used for dynamic scoping because it's not filterable" unless target_field.filterable
80
+
81
+ [field.method_name, target_name]
82
+ end.to_h
60
83
  end
61
84
 
62
85
  # determines whether association's elements can be removed
@@ -62,15 +62,15 @@ module RailsAdmin
62
62
 
63
63
  def sort_column
64
64
  if sortable == true
65
- "#{abstract_model.table_name}.#{name}"
65
+ "#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(name)}"
66
66
  elsif (sortable.is_a?(String) || sortable.is_a?(Symbol)) && sortable.to_s.include?('.') # just provide sortable, don't do anything smart
67
67
  sortable
68
68
  elsif sortable.is_a?(Hash) # just join sortable hash, don't do anything smart
69
69
  "#{sortable.keys.first}.#{sortable.values.first}"
70
- elsif association # use column on target table
71
- "#{associated_model_config.abstract_model.table_name}.#{sortable}"
70
+ elsif association? # use column on target table
71
+ "#{associated_model_config.abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}"
72
72
  else # use described column in the field conf.
73
- "#{abstract_model.table_name}.#{sortable}"
73
+ "#{abstract_model.quoted_table_name}.#{abstract_model.quote_column_name(sortable)}"
74
74
  end
75
75
  end
76
76
 
@@ -40,6 +40,14 @@ module RailsAdmin
40
40
  )
41
41
  end
42
42
 
43
+ register_instance_option :searchable do
44
+ false
45
+ end
46
+
47
+ register_instance_option :sortable do
48
+ false
49
+ end
50
+
43
51
  def resource_url(thumb = false)
44
52
  return nil unless value
45
53
 
@@ -23,6 +23,10 @@ module RailsAdmin
23
23
  (o = value) && o.send(associated_model_config.object_label_method)
24
24
  end
25
25
 
26
+ register_instance_option :allowed_methods do
27
+ nested_form ? [method_name] : [name]
28
+ end
29
+
26
30
  def selected_id
27
31
  value.try(:id).try(:to_s)
28
32
  end
@@ -38,6 +42,13 @@ module RailsAdmin
38
42
  def associated_prepopulate_params
39
43
  {associated_model_config.abstract_model.param_key => {association.foreign_key => bindings[:object].try(:id)}}
40
44
  end
45
+
46
+ def parse_input(params)
47
+ return if nested_form
48
+
49
+ id = params.delete(method_name)
50
+ params[name] = associated_model_config.abstract_model.get(id) if id
51
+ end
41
52
  end
42
53
  end
43
54
  end
@@ -48,7 +48,7 @@ module RailsAdmin
48
48
  end
49
49
 
50
50
  register_instance_option :keep_method do
51
- method_name if ::ActiveStorage.replace_on_assign_to_many
51
+ method_name if ::ActiveStorage.gem_version >= Gem::Version.new('7.1') || ::ActiveStorage.replace_on_assign_to_many
52
52
  end
53
53
 
54
54
  register_instance_option :delete_method do
@@ -70,6 +70,14 @@ module RailsAdmin
70
70
  direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},
71
71
  )
72
72
  end
73
+
74
+ register_instance_option :searchable do
75
+ false
76
+ end
77
+
78
+ register_instance_option :sortable do
79
+ false
80
+ end
73
81
  end
74
82
  end
75
83
  end
@@ -21,6 +21,7 @@ module RailsAdmin
21
21
  '%-I' => 'h', # Hour of the day, 12-hour clock (1..12)
22
22
  '%k' => 'H', # Hour of the day, 24-hour clock (0..23)
23
23
  '%l' => 'h', # Hour of the day, 12-hour clock (1..12)
24
+ '%-l' => 'h', # Hour of the day, 12-hour clock (1..12)
24
25
  '%M' => 'i', # Minute of the hour (00..59)
25
26
  '%-M' => 'i', # Minute of the hour (00..59)
26
27
  '%m' => 'm', # Month of the year (01..12)
@@ -3,9 +3,9 @@
3
3
  module RailsAdmin
4
4
  class Version
5
5
  MAJOR = 3
6
- MINOR = 1
7
- PATCH = 3
8
- PRE = nil
6
+ MINOR = 2
7
+ PATCH = 0
8
+ PRE = 'beta'
9
9
 
10
10
  class << self
11
11
  # @return [String]
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails_admin",
3
- "version": "3.1.3",
3
+ "version": "3.2.0-beta",
4
4
  "description": "RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.",
5
5
  "homepage": "https://github.com/railsadminteam/rails_admin",
6
6
  "license": "MIT",
@@ -0,0 +1,30 @@
1
+ import jQuery from "jquery";
2
+ import "jquery-ui/ui/widget.js";
3
+
4
+ (function ($) {
5
+ "use strict";
6
+
7
+ $.widget("ra.abstractSelect", {
8
+ options: {
9
+ createQuery: function (query) {
10
+ if ($.isEmptyObject(this.scopeBy)) {
11
+ return { query: query };
12
+ } else {
13
+ const filterQuery = {};
14
+ for (var field in this.scopeBy) {
15
+ const targetField = this.scopeBy[field];
16
+ const targetValue = $(`[name$="[${field}]"]`).val();
17
+ if (!filterQuery[targetField]) {
18
+ filterQuery[targetField] = [];
19
+ }
20
+ filterQuery[targetField].push(
21
+ targetValue ? { o: "is", v: targetValue } : { o: "_blank" }
22
+ );
23
+ }
24
+ return { query: query, f: filterQuery };
25
+ }
26
+ },
27
+ scopeBy: {},
28
+ },
29
+ });
30
+ })(jQuery);
@@ -17,6 +17,7 @@ import "jquery-ui/ui/widget.js";
17
17
  import "jquery-ui/ui/widgets/menu.js";
18
18
  import "jquery-ui/ui/widgets/mouse.js";
19
19
 
20
+ import "./abstract-select";
20
21
  import "./filter-box";
21
22
  import "./filtering-multiselect";
22
23
  import "./filtering-select";
@@ -26,4 +27,6 @@ import "./sidescroll";
26
27
  import "./ui";
27
28
  import "./widgets";
28
29
 
29
- Rails.start();
30
+ if (!window._rails_loaded) {
31
+ Rails.start();
32
+ }
@@ -1,13 +1,11 @@
1
1
  import jQuery from "jquery";
2
2
  import "jquery-ui/ui/widget.js";
3
3
  import I18n from "./i18n";
4
+
4
5
  (function ($) {
5
- $.widget("ra.filteringMultiselect", {
6
+ $.widget("ra.filteringMultiselect", $.ra.abstractSelect, {
6
7
  _cache: {},
7
8
  options: {
8
- createQuery: function (query) {
9
- return { query: query };
10
- },
11
9
  sortable: false,
12
10
  removable: true,
13
11
  regional: {
@@ -6,11 +6,8 @@ import I18n from "./i18n";
6
6
  (function ($) {
7
7
  "use strict";
8
8
 
9
- $.widget("ra.filteringSelect", {
9
+ $.widget("ra.filteringSelect", $.ra.abstractSelect, {
10
10
  options: {
11
- createQuery: function (query) {
12
- return { query: query };
13
- },
14
11
  minLength: 0,
15
12
  searchDelay: 200,
16
13
  remote_source: null,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.2.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Michaels-Ober
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2024-07-06 00:00:00.000000000 Z
15
+ date: 2024-07-13 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activemodel-serializers-xml
@@ -28,6 +28,20 @@ dependencies:
28
28
  - - ">="
29
29
  - !ruby/object:Gem::Version
30
30
  version: '1.0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: csv
33
+ requirement: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
31
45
  - !ruby/object:Gem::Dependency
32
46
  name: kaminari
33
47
  requirement: !ruby/object:Gem::Requirement
@@ -86,16 +100,22 @@ dependencies:
86
100
  name: turbo-rails
87
101
  requirement: !ruby/object:Gem::Requirement
88
102
  requirements:
89
- - - "~>"
103
+ - - ">="
90
104
  - !ruby/object:Gem::Version
91
105
  version: '1.0'
106
+ - - "<"
107
+ - !ruby/object:Gem::Version
108
+ version: '3'
92
109
  type: :runtime
93
110
  prerelease: false
94
111
  version_requirements: !ruby/object:Gem::Requirement
95
112
  requirements:
96
- - - "~>"
113
+ - - ">="
97
114
  - !ruby/object:Gem::Version
98
115
  version: '1.0'
116
+ - - "<"
117
+ - !ruby/object:Gem::Version
118
+ version: '3'
99
119
  - !ruby/object:Gem::Dependency
100
120
  name: bundler
101
121
  requirement: !ruby/object:Gem::Requirement
@@ -190,6 +210,7 @@ files:
190
210
  - lib/generators/rails_admin/templates/initializer.erb
191
211
  - lib/generators/rails_admin/templates/rails_admin.js
192
212
  - lib/generators/rails_admin/templates/rails_admin.scss.erb
213
+ - lib/generators/rails_admin/templates/rails_admin.vite.js
193
214
  - lib/generators/rails_admin/templates/rails_admin.webpacker.js
194
215
  - lib/generators/rails_admin/utils.rb
195
216
  - lib/rails_admin.rb
@@ -319,6 +340,7 @@ files:
319
340
  - lib/rails_admin/version.rb
320
341
  - lib/tasks/rails_admin.rake
321
342
  - package.json
343
+ - src/rails_admin/abstract-select.js
322
344
  - src/rails_admin/base.js
323
345
  - src/rails_admin/filter-box.js
324
346
  - src/rails_admin/filtering-multiselect.js
@@ -447,12 +469,13 @@ homepage: https://github.com/railsadminteam/rails_admin
447
469
  licenses:
448
470
  - MIT
449
471
  metadata: {}
450
- post_install_message: "\n ### Upgrading RailsAdmin from 2.x.x to 3.x.x ###\n\n
451
- \ Due to introduction of Webpack/Webpacker support, some additional dependencies
452
- and configuration will be needed.\n Running `bin/rails g rails_admin:install`
453
- will suggest required changes, based on the current setup of your app.\n\n For
454
- a complete list of changes, see https://github.com/railsadminteam/rails_admin/blob/master/CHANGELOG.md\n
455
- \ "
472
+ post_install_message: |
473
+ ### Upgrading RailsAdmin from 2.x.x to 3.x.x ###
474
+
475
+ Due to introduction of Webpack/Webpacker support, some additional dependencies and configuration will be needed.
476
+ Running `bin/rails g rails_admin:install` will suggest required changes, based on the current setup of your app.
477
+
478
+ For a complete list of changes, see https://github.com/railsadminteam/rails_admin/blob/master/CHANGELOG.md
456
479
  rdoc_options: []
457
480
  require_paths:
458
481
  - lib
@@ -463,11 +486,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
463
486
  version: 2.6.0
464
487
  required_rubygems_version: !ruby/object:Gem::Requirement
465
488
  requirements:
466
- - - ">="
489
+ - - ">"
467
490
  - !ruby/object:Gem::Version
468
- version: 1.8.11
491
+ version: 1.3.1
469
492
  requirements: []
470
- rubygems_version: 3.2.33
493
+ rubygems_version: 3.4.10
471
494
  signing_key:
472
495
  specification_version: 4
473
496
  summary: Admin for Rails