rails_admin 3.0.0.rc2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -7
  3. data/app/controllers/rails_admin/main_controller.rb +2 -3
  4. data/app/helpers/rails_admin/application_helper.rb +33 -11
  5. data/app/views/layouts/rails_admin/_head.html.erb +8 -5
  6. data/app/views/layouts/rails_admin/_secondary_navigation.html.erb +2 -2
  7. data/app/views/layouts/rails_admin/application.html.erb +1 -1
  8. data/app/views/rails_admin/main/export.html.erb +1 -1
  9. data/app/views/rails_admin/main/history.html.erb +1 -1
  10. data/app/views/rails_admin/main/index.html.erb +2 -2
  11. data/app/views/rails_admin/main/show.html.erb +11 -9
  12. data/lib/generators/rails_admin/install_generator.rb +2 -4
  13. data/lib/rails_admin/abstract_model.rb +2 -3
  14. data/lib/rails_admin/adapters/active_record.rb +2 -1
  15. data/lib/rails_admin/adapters/mongoid.rb +2 -2
  16. data/lib/rails_admin/config/actions/base.rb +5 -0
  17. data/lib/rails_admin/config/actions/export.rb +2 -1
  18. data/lib/rails_admin/config/actions/index.rb +2 -1
  19. data/lib/rails_admin/config/actions/new.rb +2 -1
  20. data/lib/rails_admin/config/actions/show_in_app.rb +4 -0
  21. data/lib/rails_admin/config/fields/base.rb +2 -2
  22. data/lib/rails_admin/config/fields/factories/active_storage.rb +2 -1
  23. data/lib/rails_admin/config/fields/factories/association.rb +4 -4
  24. data/lib/rails_admin/config/fields/factories/carrierwave.rb +2 -1
  25. data/lib/rails_admin/config/fields/factories/devise.rb +2 -1
  26. data/lib/rails_admin/config/fields/factories/dragonfly.rb +2 -1
  27. data/lib/rails_admin/config/fields/factories/paperclip.rb +2 -1
  28. data/lib/rails_admin/config/fields/types/datetime.rb +2 -1
  29. data/lib/rails_admin/config.rb +1 -1
  30. data/lib/rails_admin/engine.rb +6 -7
  31. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +2 -2
  32. data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +1 -1
  33. data/lib/rails_admin/version.rb +34 -1
  34. data/package.json +1 -1
  35. data/src/rails_admin/ui.js +11 -2
  36. data/vendor/assets/javascripts/rails_admin/flatpickr-with-locales.js +958 -395
  37. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 142382cf0987b581cb64996e716ad77cf9ae76dab5aa1bf019b8ca38fb7daed0
4
- data.tar.gz: 58a52e67fc458713f0245ea244e2a129f370309edc91511678ba06bbc756e9cc
3
+ metadata.gz: a20d0a9cc9b7702c63e5e92918ac89f986b2d3d1e666539fd0c16562508bdf85
4
+ data.tar.gz: 7d5784f25b6a16c0d2a05b827a8bc9990da28d056d34b2569ea628910088ae89
5
5
  SHA512:
6
- metadata.gz: 55fce15b0a7bf4f168b042ab7415fd24f0cefdb509d61efdb2f3f15de42b657bbbe24b62e686a359f18239f0c9ad36436bbd229c22b35c28be17d8f27fb5ef7f
7
- data.tar.gz: 9d076ac618ecdbb0680e7d8e7dd3472b7d0e47d10d5d12b4bdfc260c43297ded2e430a410926d0a680cbe120406e20da3678b5adb5ef2050efebe9aa8e2f8e12
6
+ metadata.gz: ea7b4265126ff76473d461cd0630feb1a4e3ad71476d2843577a25fdaea53fed0ca57b06b55dbe63615f5004151796b346f9bca2492ff71175d44faffbe24c38
7
+ data.tar.gz: 58fb832bd8e1e7c124e79eabd01393da73217714e0b52a32ea215ef1e1b2d4f33390928ed15686eeed983446d74a914ac947cd709bd67180799bf8bd9017bc4a
data/README.md CHANGED
@@ -14,12 +14,6 @@
14
14
 
15
15
  RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.
16
16
 
17
- ## Announcements
18
-
19
- ### [Action required] Security issue
20
-
21
- **RailsAdmin 2.0.1, 2.0.0 and up to 1.4.2 have been reported to have XSS vulnerability.** We strongly recommend that you upgrade RailsAdmin to 2.0.2 (and higher) or 1.4.3 as soon as possible, if you are on those versions. See [d72090ec](https://github.com/railsadminteam/rails_admin/commit/d72090ec6a07c3b9b7b48ab50f3d405f91ff4375) for the detail.
22
-
23
17
  ## Getting started
24
18
 
25
19
  - Check out [the docs][docs].
@@ -45,7 +39,7 @@ RailsAdmin is a Rails engine that provides an easy-to-use interface for managing
45
39
 
46
40
  ## Installation
47
41
 
48
- 1. On your gemfile: `gem 'rails_admin', ['>= 3.0.0.rc2', '< 4']`
42
+ 1. On your gemfile: `gem 'rails_admin', '~> 3.0'`
49
43
  2. Run `bundle install`
50
44
  3. Run `rails g rails_admin:install`
51
45
  4. Provide a namespace for the routes when asked
@@ -13,9 +13,8 @@ module RailsAdmin
13
13
 
14
14
  def list_entries(model_config = @model_config, auth_scope_key = :index, additional_scope = get_association_scope_from_params, pagination = !(params[:associated_collection] || params[:all] || params[:bulk_ids]))
15
15
  scope = model_config.scope
16
- if auth_scope = @authorization_adapter&.query(auth_scope_key, model_config.abstract_model)
17
- scope = scope.merge(auth_scope)
18
- end
16
+ auth_scope = @authorization_adapter&.query(auth_scope_key, model_config.abstract_model)
17
+ scope = scope.merge(auth_scope) if auth_scope
19
18
  scope = scope.instance_eval(&additional_scope) if additional_scope
20
19
  get_collection(model_config, scope, pagination)
21
20
  end
@@ -20,17 +20,24 @@ module RailsAdmin
20
20
  end
21
21
 
22
22
  def edit_user_link
23
- return nil unless _current_user.respond_to?(:email)
24
- return nil unless abstract_model = RailsAdmin.config(_current_user.class).abstract_model
25
-
26
- content = [
27
- RailsAdmin::Config.show_gravatar && _current_user.email.present? && image_tag("#{request.ssl? ? 'https://secure' : 'http://www'}.gravatar.com/avatar/#{Digest::MD5.hexdigest _current_user.email}?s=30", alt: ''),
28
- content_tag(:span, _current_user.email),
29
- ].compact.join.html_safe
30
- if (edit_action = RailsAdmin::Config::Actions.find(:edit, controller: controller, abstract_model: abstract_model, object: _current_user)).try(:authorized?)
31
- link_to content, rails_admin.url_for(action: edit_action.action_name, model_name: abstract_model.to_param, id: _current_user.id, controller: 'rails_admin/main'), class: 'nav-link'
23
+ return nil unless _current_user.try(:email).present?
24
+ return nil unless (abstract_model = RailsAdmin.config(_current_user.class).abstract_model)
25
+
26
+ edit_action = action(:edit, abstract_model, _current_user)
27
+ authorized = edit_action.try(:authorized?)
28
+ content = edit_user_link_label
29
+
30
+ if authorized
31
+ edit_url = rails_admin.url_for(
32
+ action_name: edit_action.action_name,
33
+ model_name: abstract_model.to_param,
34
+ controller: 'rails_admin/main',
35
+ id: _current_user.id,
36
+ )
37
+
38
+ link_to content, edit_url, class: 'nav-link'
32
39
  else
33
- content_tag :span, content
40
+ content_tag :span, content, class: 'nav-link'
34
41
  end
35
42
  end
36
43
 
@@ -162,7 +169,7 @@ module RailsAdmin
162
169
  else
163
170
  'javascript:void(0)'
164
171
  end
165
- content_tag(:a, label, {href: href, target: action.link_target, class: ['nav-link', current_action?(action) && 'active', !action.enabled? && 'disabled'].compact})
172
+ content_tag(:a, label, {href: href, target: action.link_target, class: ['nav-link', current_action?(action) && 'active', !action.enabled? && 'disabled'].compact}.merge(action.turbo? ? {} : {data: {turbo: 'false'}}))
166
173
  else
167
174
  content_tag(:span, label)
168
175
  end
@@ -206,5 +213,20 @@ module RailsAdmin
206
213
  end
207
214
  raise e
208
215
  end
216
+
217
+ private
218
+
219
+ def edit_user_link_label
220
+ [
221
+ RailsAdmin::Config.show_gravatar &&
222
+ image_tag(gravatar_url(_current_user.email), alt: ''),
223
+
224
+ content_tag(:span, _current_user.email),
225
+ ].filter(&:present?).join.html_safe
226
+ end
227
+
228
+ def gravatar_url(email)
229
+ "https://secure.gravatar.com/avatar/#{Digest::MD5.hexdigest email}?s=30"
230
+ end
209
231
  end
210
232
  end
@@ -5,13 +5,16 @@
5
5
  <%= csrf_meta_tag %>
6
6
  <% case RailsAdmin::config.asset_source
7
7
  when :webpacker %>
8
- <%= stylesheet_pack_tag "rails_admin" %>
9
- <%= javascript_pack_tag "rails_admin", async: true %>
10
- <% when :webpack, :sprockets %>
8
+ <%= stylesheet_pack_tag "rails_admin", data: {'turbo-track': 'reload'} %>
9
+ <%= javascript_pack_tag "rails_admin", async: true, data: {'turbo-track': 'reload'} %>
10
+ <% when :sprockets %>
11
11
  <% handle_asset_dependency_error do %>
12
- <%= stylesheet_link_tag "rails_admin/application.css", media: :all %>
13
- <%= javascript_include_tag "rails_admin/application.js", async: true %>
12
+ <%= stylesheet_link_tag "rails_admin/application.css", media: :all, data: {'turbo-track': 'reload'} %>
13
+ <%= javascript_include_tag "rails_admin/application.js", async: true, data: {'turbo-track': 'reload'} %>
14
14
  <% end %>
15
+ <% when :webpack %>
16
+ <%= stylesheet_link_tag "rails_admin.css", media: :all, data: {'turbo-track': 'reload'} %>
17
+ <%= javascript_include_tag "rails_admin.js", async: true, data: {'turbo-track': 'reload'} %>
15
18
  <% else
16
19
  raise "Unknown asset_source: #{RailsAdmin::config.asset_source}"
17
20
  end %>
@@ -1,7 +1,7 @@
1
1
  <ul class="navbar-nav ms-auto root_links">
2
2
  <% actions(:root).select(&:show_in_navigation).each do |action| %>
3
3
  <li class="nav-item <%= action.action_name %>_root_link">
4
- <%= link_to wording_for(:menu, action), { action: action.action_name, controller: 'rails_admin/main' }, class: ['nav-link'] %>
4
+ <%= link_to wording_for(:menu, action), { action: action.action_name, controller: 'rails_admin/main' }, {class: ['nav-link']}.merge(action.turbo? ? {} : {data: {turbo: 'false'}}) %>
5
5
  </li>
6
6
  <% end %>
7
7
  <% if main_app_root_path = (main_app.root_path rescue false) %>
@@ -17,7 +17,7 @@
17
17
  <% end %>
18
18
  <% if logout_path.present? %>
19
19
  <li class="nav-item">
20
- <%= link_to t('admin.misc.log_out'), logout_path, method: logout_method, class: 'nav-link label label-danger' %>
20
+ <%= link_to t('admin.misc.log_out'), logout_path, method: logout_method, class: 'nav-link label label-danger', data: {turbo: 'false'} %>
21
21
  </li>
22
22
  <% end %>
23
23
  <% end %>
@@ -14,7 +14,7 @@
14
14
  <%= render "layouts/rails_admin/sidebar_navigation" %>
15
15
  </div>
16
16
  <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2">
17
- <div class="container">
17
+ <div class="container-fluid">
18
18
  <%= render template: 'layouts/rails_admin/content' %>
19
19
  </div>
20
20
  </div>
@@ -1,6 +1,6 @@
1
1
  <% params = request.params.except(:action, :controller, :utf8, :page, :per_page, :format, :authenticity_token) %>
2
2
  <% visible_fields = @model_config.export.with(view: self, object: @abstract_model.model.new, controller: self.controller).visible_fields %>
3
- <%= form_tag export_path(params.merge(all: true)), method: 'post', class: "main" do %>
3
+ <%= form_tag export_path(params.merge(all: true)), method: 'post', class: "main", data: {turbo: false} do %>
4
4
  <input name="send_data" type="hidden" value="true" />
5
5
  <fieldset id="fields_to_export" class="mb-3">
6
6
  <legend>
@@ -32,7 +32,7 @@
32
32
  <% selected = (sort == property_name) %>
33
33
  <% sort_direction = (sort_reverse ? "headerSortUp" : "headerSortDown" if selected) %>
34
34
  <% sort_location = send(path_method, params.except("sort_reverse").merge(model_name: @abstract_model.to_param, sort: property_name).merge(selected && sort_reverse != "true" ? {sort_reverse: "true"} : {})) %>
35
- <th class="header <%= column[:css_class] %> <%= sort_direction if selected %>">
35
+ <th class="header <%= column[:css_class] %> <%= sort_direction if selected %>" data-href="<%= sort_location %>">
36
36
  <%= column[:link_text] %>
37
37
  </th>
38
38
  <% end %>
@@ -96,8 +96,8 @@
96
96
  <ul class="nav nav-tabs" id="scope_selector">
97
97
  <% @model_config.list.scopes.each_with_index do |scope, index| %>
98
98
  <% scope = '_all' if scope.nil? %>
99
- <li class="<%= 'active' if scope.to_s == params[:scope] || (params[:scope].blank? && index == 0) %>">
100
- <a href="<%= index_path(params.merge(scope: scope, page: nil)) %>">
99
+ <li class="nav-item">
100
+ <a href="<%= index_path(params.merge(scope: scope, page: nil)) %>" class="nav-link <%= 'active' if scope.to_s == params[:scope] || (params[:scope].blank? && index == 0) %>">
101
101
  <%= I18n.t("admin.scopes.#{@abstract_model.to_param}.#{scope}", default: I18n.t("admin.scopes.#{scope}", default: scope.to_s.titleize)) %>
102
102
  </a>
103
103
  </li>
@@ -10,16 +10,18 @@
10
10
  <%= fieldset.help %>
11
11
  </p>
12
12
  <% end %>
13
- <dl>
13
+ <div class="list-group">
14
14
  <% fields.each_with_index do |field, index| %>
15
- <dt>
16
- <span class="<%= field.type_css_class %> <%= field.css_class %> label label-info">
17
- <%= field.label %>
18
- </span>
19
- </dt>
20
- <dd class="well">
21
- <%= field.pretty_value %>
22
- </dd>
15
+ <div class="list-group-item border-0 <%= field.type_css_class %> <%= field.css_class %>">
16
+ <div class="card">
17
+ <h5 class="card-header bg-light">
18
+ <%= field.label %>
19
+ </h5>
20
+ <div class="card-body">
21
+ <%= field.pretty_value %>
22
+ </div>
23
+ </div>
24
+ </div>
23
25
  <% end %>
24
26
  </dl>
25
27
  </div>
@@ -8,7 +8,7 @@ module RailsAdmin
8
8
  include Generators::Utils::InstanceMethods
9
9
 
10
10
  argument :_namespace, type: :string, required: false, desc: 'RailsAdmin url namespace'
11
- class_option :asset, type: :string, required: false, default: nil, desc: 'Asset delivery method [options: webpack, webpacker, sprockets]'
11
+ class_option :asset, type: :string, required: false, default: nil, desc: 'Asset delivery method [options: webpacker, sprockets]'
12
12
  desc 'RailsAdmin installation generator'
13
13
 
14
14
  def install
@@ -39,9 +39,7 @@ module RailsAdmin
39
39
  def asset
40
40
  return options['asset'] if options['asset']
41
41
 
42
- if Rails.root.join('webpack.config.js').exist?
43
- 'webpack'
44
- elsif defined?(Webpacker)
42
+ if defined?(Webpacker)
45
43
  'webpacker'
46
44
  else
47
45
  'sprockets'
@@ -86,9 +86,8 @@ module RailsAdmin
86
86
  associations.each do |association|
87
87
  case association.type
88
88
  when :has_one
89
- if child = object.send(association.name)
90
- yield(association, [child])
91
- end
89
+ child = object.send(association.name)
90
+ yield(association, [child]) if child
92
91
  when :has_many
93
92
  children = object.send(association.name)
94
93
  yield(association, Array.new(children))
@@ -13,7 +13,8 @@ module RailsAdmin
13
13
  end
14
14
 
15
15
  def get(id, scope = scoped)
16
- return unless object = scope.where(primary_key => id).first
16
+ object = scope.where(primary_key => id).first
17
+ return unless object
17
18
 
18
19
  object.extend(ObjectExtension)
19
20
  end
@@ -52,10 +52,10 @@ module RailsAdmin
52
52
  scope
53
53
  rescue NoMethodError => e
54
54
  if /page/.match?(e.message)
55
- e = e.exception <<-EOM.gsub(/^\s{12}/, '')
55
+ e = e.exception <<-ERROR.gsub(/^\s{12}/, '')
56
56
  #{e.message}
57
57
  If you don't have kaminari-mongoid installed, add `gem 'kaminari-mongoid'` to your Gemfile.
58
- EOM
58
+ ERROR
59
59
  end
60
60
  raise e
61
61
  end
@@ -78,6 +78,11 @@ module RailsAdmin
78
78
  nil
79
79
  end
80
80
 
81
+ # Determines whether to navigate via Turbo Drive or not
82
+ register_instance_option :turbo? do
83
+ true
84
+ end
85
+
81
86
  # This block is evaluated in the context of the controller when action is called
82
87
  # You can access:
83
88
  # - @objects if you're on a model scope
@@ -14,7 +14,8 @@ module RailsAdmin
14
14
 
15
15
  register_instance_option :controller do
16
16
  proc do
17
- if format = params[:json] && :json || params[:csv] && :csv || params[:xml] && :xml
17
+ format = params[:json] && :json || params[:csv] && :csv || params[:xml] && :xml
18
+ if format
18
19
  request.format = format
19
20
  @schema = HashHelper.symbolize(params[:schema].slice(:except, :include, :methods, :only).permit!.to_h) if params[:schema] # to_json and to_xml expect symbols for keys AND values.
20
21
  @objects = list_entries(@model_config, :export)
@@ -20,7 +20,8 @@ module RailsAdmin
20
20
 
21
21
  register_instance_option :breadcrumb_parent do
22
22
  parent_model = bindings[:abstract_model].try(:config).try(:parent)
23
- if am = parent_model && RailsAdmin.config(parent_model).try(:abstract_model)
23
+ am = parent_model && RailsAdmin.config(parent_model).try(:abstract_model)
24
+ if am
24
25
  [:index, am]
25
26
  else
26
27
  [:dashboard]
@@ -21,7 +21,8 @@ module RailsAdmin
21
21
  @authorization_adapter&.attributes_for(:new, @abstract_model)&.each do |name, value|
22
22
  @object.send("#{name}=", value)
23
23
  end
24
- if object_params = params[@abstract_model.param_key]
24
+ object_params = params[@abstract_model.param_key]
25
+ if object_params
25
26
  sanitize_params_for!(request.xhr? ? :modal : :create)
26
27
  @object.assign_attributes(@object.attributes.merge(object_params.to_h))
27
28
  end
@@ -25,6 +25,10 @@ module RailsAdmin
25
25
  register_instance_option :link_icon do
26
26
  'fas fa-eye'
27
27
  end
28
+
29
+ register_instance_option :turbo? do
30
+ false
31
+ end
28
32
  end
29
33
  end
30
34
  end
@@ -301,14 +301,14 @@ module RailsAdmin
301
301
  def value
302
302
  bindings[:object].safe_send(name)
303
303
  rescue NoMethodError => e
304
- raise e.exception <<-EOM.gsub(/^\s{10}/, '')
304
+ raise e.exception <<-ERROR.gsub(/^\s{10}/, '')
305
305
  #{e.message}
306
306
  If you want to use a RailsAdmin virtual field(= a field without corresponding instance method),
307
307
  you should declare 'formatted_value' in the field definition.
308
308
  field :#{name} do
309
309
  formatted_value{ bindings[:object].call_some_method }
310
310
  end
311
- EOM
311
+ ERROR
312
312
  end
313
313
 
314
314
  # Reader for nested attributes
@@ -16,7 +16,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
16
16
  ["#{name}_attachment".to_sym, "#{name}_blob".to_sym]
17
17
  end
18
18
  children_fields = associations.map do |child_name|
19
- next unless child_association = parent.abstract_model.associations.detect { |p| p.name.to_sym == child_name }
19
+ child_association = parent.abstract_model.associations.detect { |p| p.name.to_sym == child_name }
20
+ next unless child_association
20
21
 
21
22
  child_field = fields.detect { |f| f.name == child_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_association, fields)
22
23
  child_field.hide unless field == child_field
@@ -3,7 +3,8 @@ require 'rails_admin/config/fields/types'
3
3
  require 'rails_admin/config/fields/types/belongs_to_association'
4
4
 
5
5
  RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
6
- if association = parent.abstract_model.associations.detect { |a| a.foreign_key == properties.name && %i[belongs_to has_and_belongs_to_many].include?(a.type) }
6
+ association = parent.abstract_model.associations.detect { |a| a.foreign_key == properties.name && %i[belongs_to has_and_belongs_to_many].include?(a.type) }
7
+ if association
7
8
  field = RailsAdmin::Config::Fields::Types.load("#{association.polymorphic? ? :polymorphic : association.type}_association").new(parent, association.name, association)
8
9
  fields << field
9
10
 
@@ -15,9 +16,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
15
16
  end.collect { |k| association.send(k) }.compact
16
17
 
17
18
  parent.abstract_model.properties.select { |p| possible_field_names.include? p.name }.each do |column|
18
- unless child_field = fields.detect { |f| f.name.to_s == column.name.to_s }
19
- child_field = RailsAdmin::Config::Fields.default_factory.call(parent, column, fields)
20
- end
19
+ child_field = fields.detect { |f| f.name.to_s == column.name.to_s }
20
+ child_field ||= RailsAdmin::Config::Fields.default_factory.call(parent, column, fields)
21
21
  child_columns << child_field
22
22
  end
23
23
 
@@ -12,7 +12,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
12
12
  fields << field
13
13
  children_fields = []
14
14
  columns.each do |children_column_name|
15
- next unless child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
15
+ child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
16
+ next unless child_properties
16
17
 
17
18
  children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)
18
19
  children_field.hide unless field == children_field
@@ -12,7 +12,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
12
12
  properties = parent.abstract_model.properties.detect { |p| ext == p.name }
13
13
  next unless properties
14
14
 
15
- unless field = fields.detect { |f| f.name == ext }
15
+ field = fields.detect { |f| f.name == ext }
16
+ unless field
16
17
  RailsAdmin::Config::Fields.default_factory.call(parent, properties, fields)
17
18
  field = fields.last
18
19
  end
@@ -9,7 +9,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
9
9
  children_fields = []
10
10
  extensions.each do |ext|
11
11
  children_column_name = "#{attachment_name}_#{ext}".to_sym
12
- next unless child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
12
+ child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
13
+ next unless child_properties
13
14
 
14
15
  children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)
15
16
  children_field.hide
@@ -10,7 +10,8 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
10
10
  children_fields = []
11
11
  extensions.each do |ext|
12
12
  children_column_name = "#{attachment_name}_#{ext}".to_sym
13
- next unless child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
13
+ child_properties = parent.abstract_model.properties.detect { |p| p.name.to_s == children_column_name.to_s }
14
+ next unless child_properties
14
15
 
15
16
  children_field = fields.detect { |f| f.name == children_column_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_properties, fields)
16
17
  children_field.hide
@@ -58,7 +58,8 @@ module RailsAdmin
58
58
  end
59
59
 
60
60
  register_instance_option :formatted_value do
61
- if time = (value || default_value)
61
+ time = (value || default_value)
62
+ if time
62
63
  ::I18n.l(time, format: strftime_format)
63
64
  else
64
65
  ''.html_safe
@@ -39,7 +39,7 @@ module RailsAdmin
39
39
  attr_accessor :included_models
40
40
 
41
41
  # Fields to be hidden in show, create and update views
42
- attr_accessor :default_hidden_fields
42
+ attr_reader :default_hidden_fields
43
43
 
44
44
  # Default items per page value used if a model level option has not
45
45
  # been configured
@@ -2,6 +2,7 @@ require 'kaminari'
2
2
  require 'nested_form'
3
3
  require 'rails'
4
4
  require 'rails_admin'
5
+ require 'rails_admin/version'
5
6
  require 'turbo-rails'
6
7
 
7
8
  module RailsAdmin
@@ -11,7 +12,7 @@ module RailsAdmin
11
12
  config.action_dispatch.rescue_responses['RailsAdmin::ActionNotAllowed'] = :forbidden
12
13
 
13
14
  initializer 'RailsAdmin precompile hook', group: :all do |app|
14
- if app.config.respond_to?(:assets)
15
+ if defined?(Sprockets)
15
16
  app.config.assets.precompile += %w[
16
17
  rails_admin/application.js
17
18
  rails_admin/application.css
@@ -42,10 +43,6 @@ module RailsAdmin
42
43
  end
43
44
  end
44
45
 
45
- rake_tasks do
46
- Dir[File.join(File.dirname(__FILE__), '../tasks/*.rake')].each { |f| load f }
47
- end
48
-
49
46
  # Check for required middlewares, users may forget to use them in Rails API mode
50
47
  config.after_initialize do |app|
51
48
  has_session_store = app.config.middleware.to_a.any? do |m|
@@ -59,20 +56,22 @@ module RailsAdmin
59
56
  unless missing.empty? && has_session_store
60
57
  configs = missing.map { |m| "config.middleware.use #{m}" }
61
58
  configs << "config.middleware.use #{app.config.session_store.try(:name) || 'ActionDispatch::Session::CookieStore'}, #{app.config.session_options}" unless has_session_store
62
- raise <<~EOM
59
+ raise <<~ERROR
63
60
  Required middlewares for RailsAdmin are not added
64
61
  To fix this, add
65
62
 
66
63
  #{configs.join("\n ")}
67
64
 
68
65
  to config/application.rb.
69
- EOM
66
+ ERROR
70
67
  end
71
68
 
72
69
  RailsAdmin::Config.initialize!
73
70
 
74
71
  # Force route reload, since it doesn't reflect RailsAdmin action configuration yet
75
72
  app.reload_routes!
73
+
74
+ RailsAdmin::Version.warn_with_js_version
76
75
  end
77
76
  end
78
77
  end
@@ -49,7 +49,7 @@ module RailsAdmin
49
49
  created_at: :created_at,
50
50
  message: :event,
51
51
  }.freeze
52
- E_VERSION_MODEL_NOT_SET = <<-EOS.strip_heredoc.freeze
52
+ E_VERSION_MODEL_NOT_SET = <<-ERROR.strip_heredoc.freeze
53
53
  Please set up PaperTrail's version model explicitly.
54
54
 
55
55
  config.audit_with :paper_trail, 'User', 'PaperTrail::Version'
@@ -58,7 +58,7 @@ module RailsAdmin
58
58
  (https://github.com/paper-trail-gem/paper_trail#6a-custom-version-classes)
59
59
  that configuration will take precedence over what you specify in
60
60
  `audit_with`.
61
- EOS
61
+ ERROR
62
62
 
63
63
  def self.setup
64
64
  raise 'PaperTrail not found' unless defined?(::PaperTrail)
@@ -7,7 +7,7 @@ module RailsAdmin
7
7
  class AuthorizationAdapter
8
8
  # This method is called first time only and used for setup
9
9
  def self.setup
10
- RailsAdmin::Extensions::ControllerExtension.include ::Pundit
10
+ RailsAdmin::Extensions::ControllerExtension.include defined?(::Pundit::Authorization) ? ::Pundit::Authorization : ::Pundit
11
11
  end
12
12
 
13
13
  # See the +authorize_with+ config method for where the initialization happens.
@@ -3,7 +3,7 @@ module RailsAdmin
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
5
  PATCH = 0
6
- PRE = 'rc2'.freeze
6
+ PRE = nil
7
7
 
8
8
  class << self
9
9
  # @return [String]
@@ -14,6 +14,39 @@ module RailsAdmin
14
14
  def js
15
15
  JSON.parse(File.read("#{__dir__}/../../package.json"))['version']
16
16
  end
17
+
18
+ def actual_js_version
19
+ case RailsAdmin.config.asset_source
20
+ when :webpacker, :webpack
21
+ js_version_from_node_modules
22
+ else
23
+ js
24
+ end
25
+ end
26
+
27
+ def warn_with_js_version
28
+ return unless Rails.env.development? || Rails.env.test?
29
+
30
+ case actual_js_version
31
+ when js
32
+ # Good
33
+ when nil
34
+ warn "[Warning] Failed to detect RailsAdmin npm package, did you run 'yarn install'?"
35
+ else
36
+ warn <<~MSG
37
+ [Warning] RailsAdmin npm package version inconsistency detected, expected #{js} but actually used is #{actual_js_version}.
38
+ This may cause partial or total malfunction of RailsAdmin frontend features.
39
+ MSG
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def js_version_from_node_modules
46
+ JSON.parse(File.read(Rails.root.join('node_modules/rails_admin/package.json')))['version']
47
+ rescue StandardError
48
+ nil
49
+ end
17
50
  end
18
51
  end
19
52
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rails_admin",
3
- "version": "3.0.0-rc2",
3
+ "version": "3.0.0",
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",
@@ -80,7 +80,7 @@ import I18n from "./i18n";
80
80
  .each(function () {
81
81
  $(this).siblings(".control-group").hide();
82
82
  });
83
- $(".form-actions .extra_buttons button")
83
+ $('button[name][type="submit"]')
84
84
  .attr("type", "button")
85
85
  .on("click", function () {
86
86
  var form = $(this).closest("form");
@@ -98,6 +98,10 @@ import I18n from "./i18n";
98
98
  $.each($("#filters_box").data("options"), function () {
99
99
  $.filters.append(this);
100
100
  });
101
+ // Workaround for https://github.com/heartcombo/devise/issues/5458
102
+ $("a[data-method]").on("click", function (event) {
103
+ window.Turbo.session.drive = false;
104
+ });
101
105
  });
102
106
 
103
107
  $(document).on("click", ".bulk-link", function (event) {
@@ -110,10 +114,15 @@ import I18n from "./i18n";
110
114
  event.preventDefault();
111
115
  $("#filters_box").html("");
112
116
  $("hr.filters_box").hide();
113
- $(this).parent().siblings("input[type='search']").val("");
117
+ $(this).siblings("input[type='search']").val("");
114
118
  $(this).parents("form").submit();
115
119
  });
116
120
 
121
+ $(document).on("click", "th.header", function (event) {
122
+ event.preventDefault();
123
+ window.Turbo.visit($(this).data("href"));
124
+ });
125
+
117
126
  $(document).on(
118
127
  "click",
119
128
  "#fields_to_export label input#check_all",