rails_admin 3.1.0.beta → 3.1.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/app/assets/javascripts/rails_admin/{application.js → application.js.erb} +8 -0
  4. data/app/assets/stylesheets/rails_admin/{application.scss → application.scss.erb} +4 -0
  5. data/app/controllers/rails_admin/main_controller.rb +2 -1
  6. data/app/helpers/rails_admin/application_helper.rb +29 -5
  7. data/app/helpers/rails_admin/main_helper.rb +5 -15
  8. data/app/views/layouts/rails_admin/_sidebar_navigation.html.erb +1 -1
  9. data/app/views/layouts/rails_admin/application.html.erb +3 -0
  10. data/app/views/rails_admin/main/_dashboard_history.html.erb +1 -1
  11. data/app/views/rails_admin/main/_form_action_text.html.erb +2 -1
  12. data/app/views/rails_admin/main/_form_file_upload.html.erb +1 -1
  13. data/app/views/rails_admin/main/_form_multiple_file_upload.html.erb +1 -1
  14. data/app/views/rails_admin/main/dashboard.html.erb +2 -2
  15. data/app/views/rails_admin/main/history.html.erb +1 -1
  16. data/app/views/rails_admin/main/index.html.erb +6 -18
  17. data/config/initializers/active_record_extensions.rb +1 -3
  18. data/config/locales/rails_admin.en.yml +3 -2
  19. data/lib/rails_admin/adapters/active_record/association.rb +1 -1
  20. data/lib/rails_admin/adapters/mongoid/extension.rb +1 -3
  21. data/lib/rails_admin/adapters/mongoid.rb +1 -1
  22. data/lib/rails_admin/config/const_load_suppressor.rb +78 -0
  23. data/lib/rails_admin/config/fields/base.rb +20 -6
  24. data/lib/rails_admin/config/fields/types/action_text.rb +4 -0
  25. data/lib/rails_admin/config/fields/types/active_storage.rb +12 -0
  26. data/lib/rails_admin/config/fields/types/belongs_to_association.rb +4 -0
  27. data/lib/rails_admin/config/fields/types/boolean.rb +4 -0
  28. data/lib/rails_admin/config/fields/types/datetime.rb +10 -0
  29. data/lib/rails_admin/config/fields/types/enum.rb +13 -2
  30. data/lib/rails_admin/config/fields/types/has_one_association.rb +4 -0
  31. data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +12 -0
  32. data/lib/rails_admin/config/fields/types/numeric.rb +4 -0
  33. data/lib/rails_admin/config/fields/types/string_like.rb +4 -0
  34. data/lib/rails_admin/config/fields/types/time.rb +4 -0
  35. data/lib/rails_admin/config/lazy_model.rb +74 -0
  36. data/lib/rails_admin/config/model.rb +3 -1
  37. data/lib/rails_admin/config/sections/list.rb +4 -0
  38. data/lib/rails_admin/config.rb +20 -37
  39. data/lib/rails_admin/engine.rb +8 -17
  40. data/lib/rails_admin/extensions/cancancan/authorization_adapter.rb +19 -4
  41. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +46 -26
  42. data/lib/rails_admin/support/es_module_processor.rb +23 -0
  43. data/lib/rails_admin/version.rb +1 -1
  44. data/lib/rails_admin.rb +4 -1
  45. data/package.json +2 -2
  46. data/src/rails_admin/filter-box.js +165 -209
  47. data/src/rails_admin/filtering-select.js +14 -5
  48. data/src/rails_admin/i18n.js +3 -1
  49. data/src/rails_admin/nested-form-hooks.js +5 -3
  50. data/src/rails_admin/remote-form.js +1 -0
  51. data/src/rails_admin/styles/base/theming.scss +15 -8
  52. data/src/rails_admin/styles/widgets.scss +1 -1
  53. data/src/rails_admin/ui.js +44 -17
  54. data/src/rails_admin/widgets.js +5 -0
  55. data/vendor/assets/fonts/rails_admin/fa-solid-900.ttf +0 -0
  56. data/vendor/assets/fonts/rails_admin/fa-solid-900.woff2 +0 -0
  57. data/vendor/assets/stylesheets/rails_admin/font-awesome.scss +4531 -2782
  58. metadata +8 -9
  59. data/lib/rails_admin/support/esmodule_preprocessor.rb +0 -37
  60. data/vendor/assets/fonts/rails_admin/fa-solid-900.eot +0 -0
  61. data/vendor/assets/fonts/rails_admin/fa-solid-900.svg +0 -5034
  62. data/vendor/assets/fonts/rails_admin/fa-solid-900.woff +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2594ac2920ab0902ebfd266356904760c4cdfe6160dbc0e7a8924a3351e1835a
4
- data.tar.gz: 252ab9a0d237488762f8a9b7a2c8c91af3dd0e048e598570722c818da78c075b
3
+ metadata.gz: 19012148f5f945b4c04e703c7f97fb74ded0442755eb953a130a81a5d58302ab
4
+ data.tar.gz: ecd7599be265ad2cbfcb2c7c09dc16afb470ca663d1d5eb6b0c0504b5770b46c
5
5
  SHA512:
6
- metadata.gz: 5ee9f27798eace802666b89d15cd92fcdf120ba44e317a87f15c5be0971d869fd6a897bbf24d0aab0dcb74859cb3dc450c098ad1af9eae4c51a4919dcd019da7
7
- data.tar.gz: 7b649a4777d4647b6154f5a35560330200d5203390c5b79771cf0cc95e7ba1aa9eab8d6414f680226f3ccc2e5cbbfb5325f4a8654f5191514214c5880cd8ed59
6
+ metadata.gz: 2c115d8a5729876233ab0980bec1398301f9c40c4d77799570c993fb521c7f9aa8b45639a308a3cd2dab2591a1455c42d793fb40875c58d4cb6896c345ec28dc
7
+ data.tar.gz: 6cb2d93962b016f5b21034958d661ec624c1553cb0aeb0be3d74c07c4fbab33fe8e15f2d1910ac6d5aec1b250d95a45f71a0faf1fc365a952c6fe9a80bceb6f1
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ source 'https://rubygems.org'
4
4
 
5
5
  gem 'appraisal', '>= 2.0'
6
6
  gem 'devise'
7
+ gem 'net-smtp', require: false
7
8
  gem 'rails'
8
9
  gem 'webpacker', require: false
9
10
  gem 'webrick', '~> 1.7'
@@ -19,3 +19,11 @@
19
19
  //= require 'rails_admin/sidescroll'
20
20
  //= require 'rails_admin/ui'
21
21
  //= require 'rails_admin/custom/ui'
22
+
23
+ <% if defined?(ActiveStorage) %>
24
+ //= require activestorage
25
+ <% end %>
26
+ <% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %>
27
+ //= require trix
28
+ //= require actiontext
29
+ <% end %>
@@ -29,3 +29,7 @@
29
29
 
30
30
  @import "rails_admin/styles/base/theming";
31
31
  @import "rails_admin/custom/theming";
32
+
33
+ <% if defined?(ActionText) && Rails.gem_version >= Gem::Version.new('7.0') %>
34
+ @import "trix";
35
+ <% end %>
@@ -123,7 +123,8 @@ module RailsAdmin
123
123
  end
124
124
 
125
125
  def get_collection(model_config, scope, pagination)
126
- eager_loads = model_config.list.fields.flat_map(&:eager_load_values)
126
+ section = @action.key == :export ? model_config.export : model_config.list
127
+ eager_loads = section.fields.flat_map(&:eager_load_values)
127
128
  options = {}
128
129
  options = options.merge(page: (params[Kaminari.config.param_name] || 1).to_i, per: (params[:per] || model_config.list.items_per_page)) if pagination
129
130
  options = options.merge(include: eager_loads) unless eager_loads.blank?
@@ -86,7 +86,7 @@ module RailsAdmin
86
86
 
87
87
  label = navigation_label || t('admin.misc.navigation')
88
88
 
89
- %(<li class='dropdown-header'>#{label}</li>#{li_stack}) if li_stack.present?
89
+ collapsible_stack(label, 'main', li_stack)
90
90
  end.join.html_safe
91
91
  end
92
92
 
@@ -101,18 +101,17 @@ module RailsAdmin
101
101
  end.join.html_safe
102
102
  label ||= t('admin.misc.root_navigation')
103
103
 
104
- %(<li class='dropdown-header'>#{label}</li>#{li_stack}) if li_stack.present?
104
+ collapsible_stack(label, 'action', li_stack)
105
105
  end.join.html_safe
106
106
  end
107
107
 
108
108
  def static_navigation
109
109
  li_stack = RailsAdmin::Config.navigation_static_links.collect do |title, url|
110
110
  content_tag(:li, link_to(title.to_s, url, target: '_blank', rel: 'noopener noreferrer', class: 'nav-link'))
111
- end.join
111
+ end.join.html_safe
112
112
 
113
113
  label = RailsAdmin::Config.navigation_static_label || t('admin.misc.navigation_static_label')
114
- li_stack = %(<li class='dropdown-header'>#{label}</li>#{li_stack}).html_safe if li_stack.present?
115
- li_stack
114
+ collapsible_stack(label, 'static', li_stack) || ''
116
115
  end
117
116
 
118
117
  def navigation(parent_groups, nodes, level = 0)
@@ -218,6 +217,15 @@ module RailsAdmin
218
217
  raise e
219
218
  end
220
219
 
220
+ # Workaround for https://github.com/rails/rails/issues/31325
221
+ def image_tag(source, options = {})
222
+ if %w[ActiveStorage::Variant ActiveStorage::VariantWithRecord ActiveStorage::Preview].include? source.class.to_s
223
+ super main_app.route_for(ActiveStorage.resolve_model_to_route, source), options
224
+ else
225
+ super
226
+ end
227
+ end
228
+
221
229
  private
222
230
 
223
231
  def edit_user_link_label
@@ -232,5 +240,21 @@ module RailsAdmin
232
240
  def gravatar_url(email)
233
241
  "https://secure.gravatar.com/avatar/#{Digest::MD5.hexdigest email}?s=30"
234
242
  end
243
+
244
+ def collapsible_stack(label, class_prefix, li_stack)
245
+ return nil unless li_stack.present?
246
+
247
+ collapse_classname = "#{class_prefix}-#{Digest::MD5.hexdigest(label)[0..7]}"
248
+ content_tag(:li, class: 'mb-1') do
249
+ content_tag(:button, 'aria-expanded': true, class: 'btn btn-toggle align-items-center rounded', data: {bs_toggle: "collapse", bs_target: ".sidebar .#{collapse_classname}"}) do
250
+ content_tag(:i, '', class: 'fas fa-chevron-down') + html_escape(' ' + label)
251
+ end +
252
+ content_tag(:div, class: "collapse show #{collapse_classname}") do
253
+ content_tag(:ul, class: 'btn-toggle-nav list-unstyled fw-normal pb-1') do
254
+ li_stack
255
+ end
256
+ end
257
+ end
258
+ end
235
259
  end
236
260
  end
@@ -42,7 +42,6 @@ module RailsAdmin
42
42
  def ordered_filter_options
43
43
  if ordered_filters
44
44
  @ordered_filter_options ||= ordered_filters.map do |duplet|
45
- options = {index: duplet[0]}
46
45
  filter_for_field = duplet[1]
47
46
  filter_name = filter_for_field.keys.first
48
47
  filter_hash = filter_for_field.values.first
@@ -50,20 +49,11 @@ module RailsAdmin
50
49
  raise "#{filter_name} is not currently filterable; filterable fields are #{filterable_fields.map(&:name).join(', ')}"
51
50
  end
52
51
 
53
- case field.type
54
- when :enum
55
- options[:select_options] = options_for_select(field.with(object: @abstract_model.model.new).enum, filter_hash['v'])
56
- when :date, :datetime, :time
57
- options[:datetimepicker_options] = field.datepicker_options
58
- end
59
- options[:label] = field.label
60
- options[:name] = field.name
61
- options[:type] = field.type
62
- options[:value] = filter_hash['v']
63
- options[:label] = field.label
64
- options[:operator] = filter_hash['o'] || field.default_filter_operator
65
- options[:required] = field.required
66
- options
52
+ field.filter_options.merge(
53
+ index: duplet[0],
54
+ operator: filter_hash['o'] || field.default_filter_operator,
55
+ value: filter_hash['v'],
56
+ )
67
57
  end
68
58
  end
69
59
  end
@@ -1,4 +1,4 @@
1
- <ul class="col-sm-3 col-md-2 btn-toggle-nav list-unstyled bg-light">
1
+ <ul class="sidebar col-sm-3 col-md-2 nav btn-toggle-nav list-unstyled bg-light">
2
2
  <%= main_navigation %>
3
3
  <%= root_navigation %>
4
4
  <%= static_navigation %>
@@ -5,6 +5,9 @@
5
5
  </head>
6
6
  <body class="rails_admin">
7
7
  <div data-i18n-options="<%= I18n.t("admin.js").to_json %>" id="admin-js"></div>
8
+ <div class="badge bg-warning" id="loading" style="display:none; position:fixed; right:20px; bottom:20px; z-index:100000">
9
+ <%= t('admin.loading') %>
10
+ </div>
8
11
  <nav class="navbar navbar-expand-md fixed-top <%= RailsAdmin::Config.navbar_css_classes.join(' ') %>">
9
12
  <%= render "layouts/rails_admin/navigation" %>
10
13
  </nav>
@@ -12,7 +12,7 @@
12
12
  </th>
13
13
  </tr>
14
14
  </thead>
15
- <tbody>
15
+ <tbody class="table-group-divider">
16
16
  <% @history.each do |t| %>
17
17
  <% abstract_model = RailsAdmin.config(t.table).abstract_model %>
18
18
  <tr>
@@ -1,7 +1,8 @@
1
1
  <%
2
2
  js_data = {
3
3
  csspath: field.css_location,
4
- jspath: field.js_location
4
+ jspath: field.js_location,
5
+ warn_dynamic_load: field.warn_dynamic_load
5
6
  }
6
7
  %>
7
8
  <%= form.rich_text_area field.method_name, field.html_attributes.reverse_merge(data: { options: js_data.to_json }) %>
@@ -6,7 +6,7 @@
6
6
  <% if value = field.pretty_value %>
7
7
  <%= value %>
8
8
  <% end %>
9
- <%= form.file_field(field.name, field.html_attributes.reverse_merge({ data: { fileupload: true }})) %>
9
+ <%= form.file_field(field.name, {data: {fileupload: true}}.deep_merge(field.html_attributes)) %>
10
10
  </div>
11
11
  <% if field.optional? && field.errors.blank? && file && field.delete_method %>
12
12
  <a class="btn btn-info btn-remove-image" data-toggle="button" href="#" role="button">
@@ -14,7 +14,7 @@
14
14
  <% end %>
15
15
  </div>
16
16
  <% end %>
17
- <%= form.file_field(field.name, field.html_attributes.reverse_merge({ data: { :"multiple-fileupload" => true }, multiple: true })) %>
17
+ <%= form.file_field(field.name, { data: { :"multiple-fileupload" => true }, multiple: true }.deep_merge(field.html_attributes)) %>
18
18
  <% if field.cache_method %>
19
19
  <%= form.hidden_field(field.cache_method) %>
20
20
  <% end %>
@@ -14,7 +14,7 @@
14
14
  <th class="shrink controls"></th>
15
15
  </tr>
16
16
  </thead>
17
- <tbody>
17
+ <tbody class="table-group-divider">
18
18
  <% @abstract_models.each do |abstract_model| %>
19
19
  <% if authorized? :index, abstract_model %>
20
20
  <% index_path = index_path(model_name: abstract_model.to_param) %>
@@ -42,7 +42,7 @@
42
42
  </div>
43
43
  </td>
44
44
  <td class="links">
45
- <ul class="inline list-inline">
45
+ <ul class="nav d-inline list-inline">
46
46
  <%= menu_for :collection, abstract_model, nil, true %>
47
47
  </ul>
48
48
  </td>
@@ -38,7 +38,7 @@
38
38
  <% end %>
39
39
  </tr>
40
40
  </thead>
41
- <tbody>
41
+ <tbody class="table-group-divider">
42
42
  <% @history.each_with_index do |object, index| %>
43
43
  <tr>
44
44
  <% unless object.created_at.nil? %>
@@ -26,26 +26,11 @@
26
26
  </a>
27
27
  <ul class="dropdown-menu dropdown-menu-end" id="filters">
28
28
  <% filterable_fields.each do |field| %>
29
- <%
30
- field_options = case field.type
31
- when :enum
32
- options_for_select(field.with(object: @abstract_model.model.new).enum)
33
- else
34
- ''
35
- end
36
- %>
37
29
  <li>
38
30
  <a
39
31
  href="#"
40
32
  class="dropdown-item"
41
- data-field-label="<%= field.label %>"
42
- data-field-name="<%= field.name %>"
43
- data-field-operator="<%= field.default_filter_operator %>"
44
- data-field-options="<%= "#{field_options}" %>"
45
- data-field-required="<%= field.required.to_s %>"
46
- data-field-type="<%= field.type %>"
47
- data-field-value=""
48
- data-field-datetimepicker-options="<%= field.try(:datepicker_options).try(:to_json) %>"
33
+ data-options="<%= field.with(view: self).filter_options.to_json %>"
49
34
  >
50
35
  <%= field.label %>
51
36
  </a>
@@ -83,6 +68,9 @@
83
68
  <i class="fas fa-times"></i>
84
69
  </button>
85
70
  </div>
71
+ <% if @model_config.list.search_help.present? %>
72
+ <div class="form-text"><%= @model_config.list.search_help %></div>
73
+ <% end %>
86
74
  </div>
87
75
  <div class="col-sm-6 text-end">
88
76
  <% if export_action %>
@@ -135,7 +123,7 @@
135
123
  <th class="last shrink"></th>
136
124
  </tr>
137
125
  </thead>
138
- <tbody>
126
+ <tbody class="table-group-divider">
139
127
  <% @objects.each do |object| %>
140
128
  <tr class="<%= @abstract_model.param_key %>_row <%= @model_config.list.with(object: object).row_css_class %>">
141
129
  <% if checkboxes %>
@@ -150,7 +138,7 @@
150
138
  </td>
151
139
  <% end %>
152
140
  <td class="last links ra-sidescroll-frozen">
153
- <ul class="inline list-inline">
141
+ <ul class="nav d-inline list-inline">
154
142
  <%= menu_for :member, @abstract_model, object, true %>
155
143
  </ul>
156
144
  </td>
@@ -4,9 +4,7 @@ ActiveSupport.on_load(:active_record) do
4
4
  module ActiveRecord
5
5
  class Base
6
6
  def self.rails_admin(&block)
7
- RailsAdmin.config do |config|
8
- config.model(self, &block)
9
- end
7
+ RailsAdmin.config(self, &block)
10
8
  end
11
9
 
12
10
  def rails_admin_default_object_label_method
@@ -1,8 +1,8 @@
1
1
  en:
2
2
  admin:
3
3
  js:
4
- true: True
5
- false: False
4
+ true: "True"
5
+ false: "False"
6
6
  is_present: Is present
7
7
  is_blank: Is blank
8
8
  date: Date ...
@@ -21,6 +21,7 @@ en:
21
21
  too_many_objects: "Too many objects, use search box above"
22
22
  no_objects: "No objects found"
23
23
  clear: Clear
24
+ loading: "Loading..."
24
25
  toggle_navigation: Toggle navigation
25
26
  home:
26
27
  name: "Home"
@@ -92,7 +92,7 @@ module RailsAdmin
92
92
  end
93
93
 
94
94
  def read_only?
95
- (klass.all.instance_eval(&scope).readonly_value if scope.is_a? Proc) ||
95
+ (klass.all.instance_exec(&scope).readonly_value if scope.is_a?(Proc) && scope.arity == 0) ||
96
96
  association.nested? ||
97
97
  false
98
98
  end
@@ -11,9 +11,7 @@ module RailsAdmin
11
11
  self.nested_attributes_options = {}
12
12
  class << self
13
13
  def rails_admin(&block)
14
- RailsAdmin.config do |config|
15
- config.model(self, &block)
16
- end
14
+ RailsAdmin.config(self, &block)
17
15
  end
18
16
 
19
17
  alias_method :accepts_nested_attributes_for_without_rails_admin, :accepts_nested_attributes_for
@@ -201,7 +201,7 @@ module RailsAdmin
201
201
  case target_association.type
202
202
  when :belongs_to, :has_and_belongs_to_many
203
203
  [{target_association.foreign_key.to_s => {'$in' => model.where('$or' => conditions).all.collect { |r| r.send(target_association.primary_key) }}}]
204
- when :has_many
204
+ when :has_many, :has_one
205
205
  [{target_association.primary_key.to_s => {'$in' => model.where('$or' => conditions).all.collect { |r| r.send(target_association.foreign_key) }}}]
206
206
  end
207
207
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsAdmin
4
+ module Config
5
+ module ConstLoadSuppressor
6
+ class << self
7
+ @original_const_missing = nil
8
+
9
+ def suppressing
10
+ raise 'Constant Loading is already suppressed' if @original_const_missing
11
+
12
+ begin
13
+ @original_const_missing = Object.method(:const_missing)
14
+ intercept_const_missing
15
+ yield
16
+ ensure
17
+ Object.define_singleton_method(:const_missing, @original_const_missing)
18
+ @original_const_missing = nil
19
+ end
20
+ end
21
+
22
+ def allowing
23
+ if @original_const_missing
24
+ begin
25
+ Object.define_singleton_method(:const_missing, @original_const_missing)
26
+ yield
27
+ ensure
28
+ intercept_const_missing
29
+ end
30
+ else
31
+ yield
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def intercept_const_missing
38
+ Object.define_singleton_method(:const_missing) do |name|
39
+ ConstProxy.new(name.to_s)
40
+ end
41
+ end
42
+ end
43
+
44
+ class ConstProxy < BasicObject
45
+ attr_reader :name
46
+
47
+ def initialize(name)
48
+ @name = name
49
+ end
50
+
51
+ def klass
52
+ @klass ||=
53
+ begin
54
+ unless ::Object.const_defined?(name)
55
+ ::Kernel.raise <<~MESSAGE
56
+ The constant #{name} is not loaded yet upon the execution of the RailsAdmin initializer.
57
+ We don't recommend to do this and may lead to issues, but if you really have to do so you can explicitly require it by adding:
58
+
59
+ require '#{name.underscore}'
60
+
61
+ on top of config/initializers/rails_admin.rb.
62
+ MESSAGE
63
+ end
64
+ name.constantize
65
+ end
66
+ end
67
+
68
+ def method_missing(method_name, *args, &block)
69
+ klass.send(method_name, *args, &block)
70
+ end
71
+
72
+ def respond_to_missing?(method_name, include_private = false)
73
+ super || klass.respond_to?(method_name, include_private)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -78,6 +78,10 @@ module RailsAdmin
78
78
  !virtual? || children_fields.first || false
79
79
  end
80
80
 
81
+ register_instance_option :search_operator do
82
+ RailsAdmin::Config.default_search_operator
83
+ end
84
+
81
85
  register_instance_option :queryable? do
82
86
  !virtual?
83
87
  end
@@ -86,8 +90,22 @@ module RailsAdmin
86
90
  !!searchable
87
91
  end
88
92
 
89
- register_instance_option :search_operator do
90
- @search_operator ||= RailsAdmin::Config.default_search_operator
93
+ register_instance_option :filter_operators do
94
+ []
95
+ end
96
+
97
+ register_instance_option :default_filter_operator do
98
+ nil
99
+ end
100
+
101
+ def filter_options
102
+ {
103
+ label: label,
104
+ name: name,
105
+ operator: default_filter_operator,
106
+ operators: filter_operators,
107
+ type: type,
108
+ }
91
109
  end
92
110
 
93
111
  # serials and dates are reversed in list, which is more natural (last modified items first).
@@ -242,10 +260,6 @@ module RailsAdmin
242
260
  []
243
261
  end
244
262
 
245
- register_instance_option :default_filter_operator do
246
- nil
247
- end
248
-
249
263
  register_instance_option :eager_load do
250
264
  false
251
265
  end
@@ -22,6 +22,10 @@ module RailsAdmin
22
22
  "https://cdnjs.cloudflare.com/ajax/libs/trix/#{version}/trix.js"
23
23
  end
24
24
 
25
+ register_instance_option :warn_dynamic_load do
26
+ true
27
+ end
28
+
25
29
  register_instance_option :partial do
26
30
  :form_action_text
27
31
  end
@@ -28,6 +28,18 @@ module RailsAdmin
28
28
  {"#{name}_attachment": :blob}
29
29
  end
30
30
 
31
+ register_instance_option :direct? do
32
+ false
33
+ end
34
+
35
+ register_instance_option :html_attributes do
36
+ {
37
+ required: required? && !value.present?,
38
+ }.merge(
39
+ direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},
40
+ )
41
+ end
42
+
31
43
  def resource_url(thumb = false)
32
44
  return nil unless value
33
45
 
@@ -9,6 +9,10 @@ module RailsAdmin
9
9
  class BelongsToAssociation < RailsAdmin::Config::Fields::Association
10
10
  RailsAdmin::Config::Fields::Types.register(self)
11
11
 
12
+ register_instance_option :filter_operators do
13
+ %w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])
14
+ end
15
+
12
16
  register_instance_option :formatted_value do
13
17
  (o = value) && o.send(associated_model_config.object_label_method)
14
18
  end
@@ -24,6 +24,10 @@ module RailsAdmin
24
24
  }
25
25
  end
26
26
 
27
+ register_instance_option :filter_operators do
28
+ %w[_discard true false] + (required? ? [] : %w[_separator _present _blank])
29
+ end
30
+
27
31
  register_instance_option :nullable? do
28
32
  properties&.nullable?
29
33
  end
@@ -18,6 +18,16 @@ module RailsAdmin
18
18
  params[name] = parse_value(params[name]) if params[name]
19
19
  end
20
20
 
21
+ register_instance_option :filter_operators do
22
+ %w[default between today yesterday this_week last_week] + (required? ? [] : %w[_separator _not_null _null])
23
+ end
24
+
25
+ def filter_options
26
+ super.merge(
27
+ datetimepicker_options: datepicker_options,
28
+ )
29
+ end
30
+
21
31
  register_instance_option :date_format do
22
32
  :long
23
33
  end
@@ -9,16 +9,27 @@ module RailsAdmin
9
9
  class Enum < RailsAdmin::Config::Fields::Base
10
10
  RailsAdmin::Config::Fields::Types.register(self)
11
11
 
12
+ register_instance_option :filter_operators do
13
+ %w[_discard] +
14
+ enum.map do |label, value|
15
+ {label: label, value: value || label}
16
+ end + (required? ? [] : %w[_separator _present _blank])
17
+ end
18
+
12
19
  register_instance_option :partial do
13
20
  :form_enumeration
14
21
  end
15
22
 
16
23
  register_instance_option :enum_method do
17
- @enum_method ||= bindings[:object].class.respond_to?("#{name}_enum") || bindings[:object].respond_to?("#{name}_enum") ? "#{name}_enum" : name
24
+ @enum_method ||= bindings[:object].class.respond_to?("#{name}_enum") || (bindings[:object] || abstract_model.model.new).respond_to?("#{name}_enum") ? "#{name}_enum" : name
18
25
  end
19
26
 
20
27
  register_instance_option :enum do
21
- bindings[:object].class.respond_to?(enum_method) ? bindings[:object].class.send(enum_method) : bindings[:object].send(enum_method)
28
+ if abstract_model.model.respond_to?(enum_method)
29
+ abstract_model.model.send(enum_method)
30
+ else
31
+ (bindings[:object] || abstract_model.model.new).send(enum_method)
32
+ end
22
33
  end
23
34
 
24
35
  register_instance_option :pretty_value do
@@ -10,6 +10,10 @@ module RailsAdmin
10
10
  # Register field type for the type loader
11
11
  RailsAdmin::Config::Fields::Types.register(self)
12
12
 
13
+ register_instance_option :filter_operators do
14
+ %w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])
15
+ end
16
+
13
17
  register_instance_option :partial do
14
18
  nested_form ? :form_nested_one : :form_filtering_select
15
19
  end
@@ -58,6 +58,18 @@ module RailsAdmin
58
58
  register_instance_option :eager_load do
59
59
  {"#{name}_attachments": :blob}
60
60
  end
61
+
62
+ register_instance_option :direct? do
63
+ false
64
+ end
65
+
66
+ register_instance_option :html_attributes do
67
+ {
68
+ required: required? && !value.present?,
69
+ }.merge(
70
+ direct? && {data: {direct_upload_url: bindings[:view].main_app.rails_direct_uploads_url}} || {},
71
+ )
72
+ end
61
73
  end
62
74
  end
63
75
  end
@@ -10,6 +10,10 @@ module RailsAdmin
10
10
  # Register field type for the type loader
11
11
  RailsAdmin::Config::Fields::Types.register(self)
12
12
 
13
+ register_instance_option :filter_operators do
14
+ %w[default between] + (required? ? [] : %w[_separator _not_null _null])
15
+ end
16
+
13
17
  register_instance_option :view_helper do
14
18
  :number_field
15
19
  end
@@ -7,6 +7,10 @@ module RailsAdmin
7
7
  module Fields
8
8
  module Types
9
9
  class StringLike < RailsAdmin::Config::Fields::Base
10
+ register_instance_option :filter_operators do
11
+ %w[_discard like not_like is starts_with ends_with] + (required? ? [] : %w[_separator _present _blank])
12
+ end
13
+
10
14
  register_instance_option :treat_empty_as_nil? do
11
15
  properties.try(:nullable?)
12
16
  end