rails_admin 1.3.0 → 1.4.0
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -4
- data/README.md +4 -4
- data/app/assets/javascripts/rails_admin/jquery-ui.js.erb +8 -0
- data/app/assets/javascripts/rails_admin/ra.filter-box.js +4 -0
- data/app/assets/javascripts/rails_admin/ra.widgets.coffee +17 -0
- data/app/assets/javascripts/rails_admin/rails_admin.js +1 -3
- data/app/views/rails_admin/main/_form_file_upload.html.haml +1 -1
- data/app/views/rails_admin/main/_form_multiple_file_upload.html.haml +14 -0
- data/lib/rails_admin/adapters/active_record.rb +3 -0
- data/lib/rails_admin/adapters/mongoid.rb +2 -2
- data/lib/rails_admin/adapters/mongoid/abstract_object.rb +2 -3
- data/lib/rails_admin/adapters/mongoid/association.rb +14 -3
- data/lib/rails_admin/adapters/mongoid/property.rb +2 -2
- data/lib/rails_admin/config.rb +9 -1
- data/lib/rails_admin/config/fields.rb +1 -0
- data/lib/rails_admin/config/fields/factories/active_storage.rb +30 -0
- data/lib/rails_admin/config/fields/factories/carrierwave.rb +3 -1
- data/lib/rails_admin/config/fields/types/active_storage.rb +44 -0
- data/lib/rails_admin/config/fields/types/all.rb +4 -0
- data/lib/rails_admin/config/fields/types/code_mirror.rb +4 -4
- data/lib/rails_admin/config/fields/types/file_upload.rb +1 -1
- data/lib/rails_admin/config/fields/types/multiple_active_storage.rb +49 -0
- data/lib/rails_admin/config/fields/types/multiple_carrierwave.rb +44 -0
- data/lib/rails_admin/config/fields/types/multiple_file_upload.rb +110 -0
- data/lib/rails_admin/config/has_fields.rb +1 -1
- data/lib/rails_admin/engine.rb +16 -0
- data/lib/rails_admin/extensions/cancancan.rb +1 -1
- data/lib/rails_admin/extensions/cancancan/authorization_adapter.rb +28 -36
- data/lib/rails_admin/extensions/pundit/authorization_adapter.rb +2 -2
- data/lib/rails_admin/version.rb +1 -1
- metadata +17 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 361208518b5b304581718ddc22d54ee97adcbaad
|
|
4
|
+
data.tar.gz: 807e4d91a69a5377444885331a087e25ab65c891
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40e5f564f367ad3c53220737654301ff01df27ef448044d1d933397e3ac28d6fb2559e0dc6cfb4bbfe57cbc71194dcab9ea46ffcc263d3d71949a8935126f30a
|
|
7
|
+
data.tar.gz: b08875e67144b03c5ab98789772067f6e3765c2e93e1d226800b742e68f685cbe5a829c04d35123560e98e80dcb2babbba9b1cb6b1c97a0fd2983968c461b436
|
data/Gemfile
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
3
|
gem 'appraisal', '>= 2.0'
|
|
4
|
-
gem 'rails'
|
|
4
|
+
gem 'rails'
|
|
5
5
|
gem 'haml'
|
|
6
6
|
gem 'devise'
|
|
7
7
|
|
|
@@ -9,7 +9,7 @@ group :active_record do
|
|
|
9
9
|
gem 'paper_trail'
|
|
10
10
|
|
|
11
11
|
platforms :ruby, :mswin, :mingw do
|
|
12
|
-
gem 'mysql2', '
|
|
12
|
+
gem 'mysql2', '>= 0.3.14'
|
|
13
13
|
gem 'sqlite3', '>= 1.3'
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -19,8 +19,6 @@ group :development, :test do
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
group :test do
|
|
22
|
-
gem 'cancan', '>= 1.6'
|
|
23
|
-
gem 'cancancan', '~> 1.12.0'
|
|
24
22
|
gem 'carrierwave', '>= 0.8'
|
|
25
23
|
gem 'coveralls'
|
|
26
24
|
gem 'database_cleaner', ['>= 1.2', '!= 1.4.0', '!= 1.5.0']
|
data/README.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
[][gem]
|
|
4
4
|
[][travis]
|
|
5
|
-
[][gemnasium]
|
|
6
|
-
[][codeclimate]
|
|
7
5
|
[][coveralls]
|
|
8
6
|
[][inch]
|
|
7
|
+
[][codeclimate]
|
|
8
|
+
[][semver]
|
|
9
9
|
|
|
10
10
|
[gem]: https://rubygems.org/gems/rails_admin
|
|
11
11
|
[travis]: https://travis-ci.org/sferik/rails_admin
|
|
12
|
-
[gemnasium]: https://gemnasium.com/sferik/rails_admin
|
|
13
|
-
[codeclimate]: https://codeclimate.com/github/sferik/rails_admin
|
|
14
12
|
[coveralls]: https://coveralls.io/r/sferik/rails_admin
|
|
15
13
|
[inch]: http://inch-ci.org/github/sferik/rails_admin
|
|
14
|
+
[codeclimate]: https://codeclimate.com/github/sferik/rails_admin
|
|
15
|
+
[semver]: https://dependabot.com/compatibility-score.html?dependency-name=rails_admin&package-manager=bundler&version-scheme=semver
|
|
16
16
|
|
|
17
17
|
RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data.
|
|
18
18
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<% require_asset "jquery-ui/effect" %>
|
|
2
|
+
<% if Jquery::Ui::Rails::JQUERY_UI_VERSION >= '1.12' %>
|
|
3
|
+
<% require_asset "jquery-ui/widgets/sortable" %>
|
|
4
|
+
<% require_asset "jquery-ui/widgets/autocomplete" %>
|
|
5
|
+
<% else %>
|
|
6
|
+
<% require_asset "jquery-ui/sortable" %>
|
|
7
|
+
<% require_asset "jquery-ui/autocomplete" %>
|
|
8
|
+
<% end %>
|
|
@@ -157,7 +157,11 @@
|
|
|
157
157
|
break;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
var filterContainerId = field_name + '-' + index + '-filter-container';
|
|
161
|
+
$('p#' + filterContainerId).remove();
|
|
162
|
+
|
|
160
163
|
var $content = $('<p>')
|
|
164
|
+
.attr('id', filterContainerId)
|
|
161
165
|
.addClass('filter form-search')
|
|
162
166
|
.append(
|
|
163
167
|
$('<span class="label label-info form-label"></span>')
|
|
@@ -70,6 +70,23 @@ $(document).on 'rails_admin.dom_ready', (e, content) ->
|
|
|
70
70
|
else
|
|
71
71
|
image_container.hide()
|
|
72
72
|
|
|
73
|
+
# multiple-fileupload-preview
|
|
74
|
+
|
|
75
|
+
content.find('[data-multiple-fileupload]').change ->
|
|
76
|
+
input = this
|
|
77
|
+
$("#" + input.id).parent().children(".preview").remove()
|
|
78
|
+
for file in input.files
|
|
79
|
+
ext = file.name.split('.').pop().toLowerCase()
|
|
80
|
+
if $.inArray(ext, ['gif','png','jpg','jpeg','bmp']) == -1
|
|
81
|
+
continue
|
|
82
|
+
image_container = $('<img />').addClass('preview').addClass('img-thumbnail')
|
|
83
|
+
do (image_container) ->
|
|
84
|
+
reader = new FileReader()
|
|
85
|
+
reader.onload = (e) ->
|
|
86
|
+
image_container.attr "src", e.target.result
|
|
87
|
+
reader.readAsDataURL file
|
|
88
|
+
$("#" + input.id).parent().append($('<div></div>').addClass('preview').append(image_container))
|
|
89
|
+
|
|
73
90
|
# filtering-multiselect
|
|
74
91
|
|
|
75
92
|
content.find('[data-filteringmultiselect]').each ->
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
//= require 'jquery'
|
|
2
2
|
//= require 'jquery_ujs'
|
|
3
3
|
//= require 'jquery.remotipart'
|
|
4
|
-
//= require 'jquery-ui
|
|
5
|
-
//= require 'jquery-ui/sortable'
|
|
6
|
-
//= require 'jquery-ui/autocomplete'
|
|
4
|
+
//= require 'rails_admin/jquery-ui'
|
|
7
5
|
//= require 'rails_admin/moment-with-locales'
|
|
8
6
|
//= require 'rails_admin/bootstrap-datetimepicker'
|
|
9
7
|
//= require 'rails_admin/jquery.colorpicker'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
- field.attachments.each_with_index do |attachment, i|
|
|
2
|
+
.toggle
|
|
3
|
+
= attachment.pretty_value
|
|
4
|
+
- if field.delete_method
|
|
5
|
+
%a.btn.btn-info.btn-remove-image{href: '#', :'data-toggle' => 'button', role: 'button', onclick: "$(this).siblings('[type=checkbox]').click(); $(this).parent('.toggle').toggle('slow'); jQuery(this).toggleClass('btn-danger btn-info'); return false;"}
|
|
6
|
+
%i.icon-white.icon-trash
|
|
7
|
+
= I18n.t('admin.actions.delete.menu').capitalize + " #{field.label.downcase} ##{i + 1}"
|
|
8
|
+
|
|
9
|
+
= form.check_box(field.delete_method, {multiple:true, style: 'display:none;'}, attachment.delete_key, nil)
|
|
10
|
+
|
|
11
|
+
= form.file_field(field.name, field.html_attributes.reverse_merge({ data: { :"multiple-fileupload" => true }, multiple: true }))
|
|
12
|
+
|
|
13
|
+
- if field.cache_method
|
|
14
|
+
= form.hidden_field(field.cache_method)
|
|
@@ -155,6 +155,8 @@ module RailsAdmin
|
|
|
155
155
|
case @type
|
|
156
156
|
when :boolean
|
|
157
157
|
boolean_unary_operators
|
|
158
|
+
when :integer, :decimal, :float
|
|
159
|
+
numeric_unary_operators
|
|
158
160
|
else
|
|
159
161
|
generic_unary_operators
|
|
160
162
|
end
|
|
@@ -181,6 +183,7 @@ module RailsAdmin
|
|
|
181
183
|
'_not_empty' => ["(#{@column} IS NOT NULL)"],
|
|
182
184
|
)
|
|
183
185
|
end
|
|
186
|
+
alias_method :numeric_unary_operators, :boolean_unary_operators
|
|
184
187
|
|
|
185
188
|
def range_filter(min, max)
|
|
186
189
|
if min && max
|
|
@@ -83,7 +83,7 @@ module RailsAdmin
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def embedded?
|
|
86
|
-
|
|
86
|
+
associations.detect { |a| a.macro == :embedded_in }
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
def cyclic?
|
|
@@ -150,7 +150,7 @@ module RailsAdmin
|
|
|
150
150
|
|
|
151
151
|
def parse_collection_name(column)
|
|
152
152
|
collection_name, column_name = column.split('.')
|
|
153
|
-
if
|
|
153
|
+
if associations.detect { |a| a.name == collection_name.to_sym }.try(:embeds?)
|
|
154
154
|
[table_name, column]
|
|
155
155
|
else
|
|
156
156
|
[collection_name, column_name]
|
|
@@ -7,6 +7,7 @@ module RailsAdmin
|
|
|
7
7
|
def initialize(object)
|
|
8
8
|
super
|
|
9
9
|
object.associations.each do |name, association|
|
|
10
|
+
association = Association.new(association, object.class)
|
|
10
11
|
if [:has_many, :references_many].include? association.macro
|
|
11
12
|
instance_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
12
13
|
def #{name.to_s.singularize}_ids
|
|
@@ -28,9 +29,7 @@ RUBY
|
|
|
28
29
|
def #{name}_id=(item_id)
|
|
29
30
|
item = (#{association.klass}.find(item_id) rescue nil)
|
|
30
31
|
return unless item
|
|
31
|
-
unless persisted?
|
|
32
|
-
item.update_attribute('#{association.foreign_key}', id)
|
|
33
|
-
end
|
|
32
|
+
item.update_attribute('#{association.foreign_key}', id) unless persisted?
|
|
34
33
|
super item.id
|
|
35
34
|
end
|
|
36
35
|
RUBY
|
|
@@ -45,7 +45,7 @@ module RailsAdmin
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def foreign_key
|
|
48
|
-
return
|
|
48
|
+
return if embeds?
|
|
49
49
|
association.foreign_key.to_sym rescue nil
|
|
50
50
|
end
|
|
51
51
|
|
|
@@ -82,7 +82,7 @@ module RailsAdmin
|
|
|
82
82
|
|
|
83
83
|
def nested_options
|
|
84
84
|
nested = nested_attributes_options.try { |o| o[name] }
|
|
85
|
-
if !nested && [:embeds_one, :embeds_many].include?(macro.to_sym) && !
|
|
85
|
+
if !nested && [:embeds_one, :embeds_many].include?(macro.to_sym) && !cyclic?
|
|
86
86
|
raise <<-MSG.gsub(/^\s+/, '')
|
|
87
87
|
Embbeded association without accepts_nested_attributes_for can't be handled by RailsAdmin,
|
|
88
88
|
because embedded model doesn't have top-level access.
|
|
@@ -96,13 +96,24 @@ module RailsAdmin
|
|
|
96
96
|
true
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
+
def macro
|
|
100
|
+
association.try(:macro) || association.class.name.split('::').last.underscore.to_sym
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def embeds?
|
|
104
|
+
[:embeds_one, :embeds_many].include?(macro)
|
|
105
|
+
end
|
|
106
|
+
|
|
99
107
|
private
|
|
100
108
|
|
|
101
109
|
def inverse_of_field
|
|
102
110
|
association.respond_to?(:inverse_of_field) && association.inverse_of_field
|
|
103
111
|
end
|
|
104
112
|
|
|
105
|
-
|
|
113
|
+
def cyclic?
|
|
114
|
+
association.respond_to?(:cyclic?) ? association.cyclic? : association.cyclic
|
|
115
|
+
end
|
|
116
|
+
|
|
106
117
|
delegate :nested_attributes_options, to: :model, prefix: false
|
|
107
118
|
delegate :polymorphic_parents, to: RailsAdmin::AbstractModel
|
|
108
119
|
end
|
|
@@ -70,8 +70,8 @@ module RailsAdmin
|
|
|
70
70
|
private
|
|
71
71
|
|
|
72
72
|
def object_field_type
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
association = Association.new model.relations.values.detect { |r| r.try(:foreign_key).try(:to_sym) == name }, model
|
|
74
|
+
if [:belongs_to, :referenced_in, :embedded_in].include?(association.macro)
|
|
75
75
|
:bson_object_id
|
|
76
76
|
else
|
|
77
77
|
:string
|
data/lib/rails_admin/config.rb
CHANGED
|
@@ -207,7 +207,7 @@ module RailsAdmin
|
|
|
207
207
|
|
|
208
208
|
# pool of all found model names from the whole application
|
|
209
209
|
def models_pool
|
|
210
|
-
excluded = (excluded_models.collect(&:to_s) + %w(RailsAdmin::History PaperTrail::Version PaperTrail::VersionAssociation))
|
|
210
|
+
excluded = (excluded_models.collect(&:to_s) + %w(RailsAdmin::History PaperTrail::Version PaperTrail::VersionAssociation ActiveStorage::Attachment ActiveStorage::Blob))
|
|
211
211
|
|
|
212
212
|
(viable_models - excluded).uniq.sort
|
|
213
213
|
end
|
|
@@ -304,6 +304,14 @@ module RailsAdmin
|
|
|
304
304
|
@registry.delete(key)
|
|
305
305
|
end
|
|
306
306
|
|
|
307
|
+
# Reset all models configuration
|
|
308
|
+
# Used to clear all configurations when reloading code in development.
|
|
309
|
+
# @see RailsAdmin::Engine
|
|
310
|
+
# @see RailsAdmin::Config.registry
|
|
311
|
+
def reset_all_models
|
|
312
|
+
@registry = {}
|
|
313
|
+
end
|
|
314
|
+
|
|
307
315
|
# Get all models that are configured as visible sorted by their weight and label.
|
|
308
316
|
#
|
|
309
317
|
# @see RailsAdmin::Config::Hideable
|
|
@@ -83,4 +83,5 @@ require 'rails_admin/config/fields/factories/paperclip'
|
|
|
83
83
|
require 'rails_admin/config/fields/factories/dragonfly'
|
|
84
84
|
require 'rails_admin/config/fields/factories/carrierwave'
|
|
85
85
|
require 'rails_admin/config/fields/factories/refile'
|
|
86
|
+
require 'rails_admin/config/fields/factories/active_storage'
|
|
86
87
|
require 'rails_admin/config/fields/factories/association'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'rails_admin/config/fields'
|
|
2
|
+
require 'rails_admin/config/fields/types'
|
|
3
|
+
require 'rails_admin/config/fields/types/file_upload'
|
|
4
|
+
|
|
5
|
+
RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
|
|
6
|
+
if defined?(::ActiveStorage) && properties.is_a?(RailsAdmin::Adapters::ActiveRecord::Association) && (match = /\A(.+)_attachments?\Z/.match properties.name) && properties.klass.to_s == 'ActiveStorage::Attachment'
|
|
7
|
+
name = match[1]
|
|
8
|
+
field = RailsAdmin::Config::Fields::Types.load(
|
|
9
|
+
properties.type == :has_many ? :multiple_active_storage : :active_storage,
|
|
10
|
+
).new(parent, name, properties)
|
|
11
|
+
fields << field
|
|
12
|
+
associations =
|
|
13
|
+
if properties.type == :has_many
|
|
14
|
+
["#{name}_attachments".to_sym, "#{name}_blobs".to_sym]
|
|
15
|
+
else
|
|
16
|
+
["#{name}_attachment".to_sym, "#{name}_blob".to_sym]
|
|
17
|
+
end
|
|
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 }
|
|
20
|
+
child_field = fields.detect { |f| f.name == child_name } || RailsAdmin::Config::Fields.default_factory.call(parent, child_association, fields)
|
|
21
|
+
child_field.hide unless field == child_field
|
|
22
|
+
child_field.filterable(false) unless field == child_field
|
|
23
|
+
child_field.name
|
|
24
|
+
end.flatten.compact
|
|
25
|
+
field.children_fields(children_fields)
|
|
26
|
+
true
|
|
27
|
+
else
|
|
28
|
+
false
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -6,7 +6,9 @@ RailsAdmin::Config::Fields.register_factory do |parent, properties, fields|
|
|
|
6
6
|
model = parent.abstract_model.model
|
|
7
7
|
if defined?(::CarrierWave) && model.is_a?(CarrierWave::Mount) && model.uploaders.include?(attachment_name = properties.name.to_s.chomp('_file_name').to_sym)
|
|
8
8
|
columns = [model.uploader_options[attachment_name][:mount_on] || attachment_name, "#{attachment_name}_content_type".to_sym, "#{attachment_name}_file_size".to_sym]
|
|
9
|
-
field = RailsAdmin::Config::Fields::Types.load(
|
|
9
|
+
field = RailsAdmin::Config::Fields::Types.load(
|
|
10
|
+
[:serialized, :json].include?(properties.type) ? :multiple_carrierwave : :carrierwave,
|
|
11
|
+
).new(parent, attachment_name, properties)
|
|
10
12
|
fields << field
|
|
11
13
|
children_fields = []
|
|
12
14
|
columns.each do |children_column_name|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'rails_admin/config/fields/types/file_upload'
|
|
2
|
+
|
|
3
|
+
module RailsAdmin
|
|
4
|
+
module Config
|
|
5
|
+
module Fields
|
|
6
|
+
module Types
|
|
7
|
+
class ActiveStorage < RailsAdmin::Config::Fields::Types::FileUpload
|
|
8
|
+
RailsAdmin::Config::Fields::Types.register(self)
|
|
9
|
+
|
|
10
|
+
register_instance_option :thumb_method do
|
|
11
|
+
{resize: '100x100>'}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
register_instance_option :delete_method do
|
|
15
|
+
"remove_#{name}" if bindings[:object].respond_to?("remove_#{name}")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
register_instance_option :image? do
|
|
19
|
+
if value
|
|
20
|
+
value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def resource_url(thumb = false)
|
|
25
|
+
return nil unless value
|
|
26
|
+
if thumb && value.variable?
|
|
27
|
+
variant = value.variant(thumb)
|
|
28
|
+
Rails.application.routes.url_helpers.rails_blob_representation_path(
|
|
29
|
+
variant.blob.signed_id, variant.variation.key, variant.blob.filename, only_path: true
|
|
30
|
+
)
|
|
31
|
+
else
|
|
32
|
+
Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def value
|
|
37
|
+
attachment = super
|
|
38
|
+
attachment if attachment && attachment.attached?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'rails_admin/config/fields/types/active_record_enum'
|
|
2
|
+
require 'rails_admin/config/fields/types/active_storage'
|
|
2
3
|
require 'rails_admin/config/fields/types/belongs_to_association'
|
|
3
4
|
require 'rails_admin/config/fields/types/boolean'
|
|
4
5
|
require 'rails_admin/config/fields/types/bson_object_id'
|
|
@@ -11,6 +12,9 @@ require 'rails_admin/config/fields/types/file_upload'
|
|
|
11
12
|
require 'rails_admin/config/fields/types/paperclip'
|
|
12
13
|
require 'rails_admin/config/fields/types/carrierwave'
|
|
13
14
|
require 'rails_admin/config/fields/types/refile'
|
|
15
|
+
require 'rails_admin/config/fields/types/multiple_file_upload'
|
|
16
|
+
require 'rails_admin/config/fields/types/multiple_active_storage'
|
|
17
|
+
require 'rails_admin/config/fields/types/multiple_carrierwave'
|
|
14
18
|
require 'rails_admin/config/fields/types/float'
|
|
15
19
|
require 'rails_admin/config/fields/types/has_and_belongs_to_many_association'
|
|
16
20
|
require 'rails_admin/config/fields/types/has_many_association'
|
|
@@ -19,19 +19,19 @@ module RailsAdmin
|
|
|
19
19
|
# Pass the location of the theme and mode for Codemirror
|
|
20
20
|
register_instance_option :assets do
|
|
21
21
|
{
|
|
22
|
-
mode: '
|
|
23
|
-
theme: '
|
|
22
|
+
mode: ::ActionController::Base.helpers.asset_path('codemirror/modes/css.js'),
|
|
23
|
+
theme: ::ActionController::Base.helpers.asset_path('codemirror/themes/night.css'),
|
|
24
24
|
}
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
# Use this if you want to point to a cloud instances of CodeMirror
|
|
28
28
|
register_instance_option :js_location do
|
|
29
|
-
'
|
|
29
|
+
::ActionController::Base.helpers.asset_path('codemirror.js')
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Use this if you want to point to a cloud instances of CodeMirror
|
|
33
33
|
register_instance_option :css_location do
|
|
34
|
-
'
|
|
34
|
+
::ActionController::Base.helpers.asset_path('codemirror.css')
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
register_instance_option :partial do
|
|
@@ -36,7 +36,7 @@ module RailsAdmin
|
|
|
36
36
|
image_html = v.image_tag(thumb_url, class: 'img-thumbnail')
|
|
37
37
|
url != thumb_url ? v.link_to(image_html, url, target: '_blank') : image_html
|
|
38
38
|
else
|
|
39
|
-
v.link_to(
|
|
39
|
+
v.link_to(value, url, target: '_blank')
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'rails_admin/config/fields/types/multiple_file_upload'
|
|
2
|
+
|
|
3
|
+
module RailsAdmin
|
|
4
|
+
module Config
|
|
5
|
+
module Fields
|
|
6
|
+
module Types
|
|
7
|
+
class MultipleActiveStorage < RailsAdmin::Config::Fields::Types::MultipleFileUpload
|
|
8
|
+
RailsAdmin::Config::Fields::Types.register(self)
|
|
9
|
+
|
|
10
|
+
class ActiveStorageAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment
|
|
11
|
+
register_instance_option :thumb_method do
|
|
12
|
+
{resize: '100x100>'}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
register_instance_option :delete_key do
|
|
16
|
+
value.id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
register_instance_option :image? do
|
|
20
|
+
if value
|
|
21
|
+
value.filename.to_s.split('.').last =~ /jpg|jpeg|png|gif|svg/i
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resource_url(thumb = false)
|
|
26
|
+
return nil unless value
|
|
27
|
+
if thumb && value.variable?
|
|
28
|
+
variant = value.variant(thumb_method)
|
|
29
|
+
Rails.application.routes.url_helpers.rails_blob_representation_path(
|
|
30
|
+
variant.blob.signed_id, variant.variation.key, variant.blob.filename, only_path: true
|
|
31
|
+
)
|
|
32
|
+
else
|
|
33
|
+
Rails.application.routes.url_helpers.rails_blob_path(value, only_path: true)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
register_instance_option :attachment_class do
|
|
39
|
+
ActiveStorageAttachment
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
register_instance_option :delete_method do
|
|
43
|
+
"remove_#{name}" if bindings[:object].respond_to?("remove_#{name}")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'rails_admin/config/fields/types/multiple_file_upload'
|
|
2
|
+
|
|
3
|
+
module RailsAdmin
|
|
4
|
+
module Config
|
|
5
|
+
module Fields
|
|
6
|
+
module Types
|
|
7
|
+
class MultipleCarrierwave < RailsAdmin::Config::Fields::Types::MultipleFileUpload
|
|
8
|
+
RailsAdmin::Config::Fields::Types.register(self)
|
|
9
|
+
|
|
10
|
+
class CarrierwaveAttachment < RailsAdmin::Config::Fields::Types::MultipleFileUpload::AbstractAttachment
|
|
11
|
+
register_instance_option :thumb_method do
|
|
12
|
+
@thumb_method ||= ((versions = value.versions.keys).detect { |k| k.in?([:thumb, :thumbnail, 'thumb', 'thumbnail']) } || versions.first.to_s)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
register_instance_option :delete_key do
|
|
16
|
+
value.file.identifier
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def resource_url(thumb = false)
|
|
20
|
+
return nil unless value
|
|
21
|
+
thumb.present? ? value.send(thumb).url : value.url
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
register_instance_option :attachment_class do
|
|
26
|
+
CarrierwaveAttachment
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
register_instance_option :cache_method do
|
|
30
|
+
"#{name}_cache"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
register_instance_option :delete_method do
|
|
34
|
+
"delete_#{name}" if bindings[:object].respond_to?("delete_#{name}")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def value
|
|
38
|
+
bindings[:object].send(name)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
module RailsAdmin
|
|
2
|
+
module Config
|
|
3
|
+
module Fields
|
|
4
|
+
module Types
|
|
5
|
+
class MultipleFileUpload < RailsAdmin::Config::Fields::Base
|
|
6
|
+
RailsAdmin::Config::Fields::Types.register(self)
|
|
7
|
+
|
|
8
|
+
class AbstractAttachment
|
|
9
|
+
include RailsAdmin::Config::Proxyable
|
|
10
|
+
include RailsAdmin::Config::Configurable
|
|
11
|
+
|
|
12
|
+
attr_reader :value
|
|
13
|
+
|
|
14
|
+
def initialize(value)
|
|
15
|
+
@value = value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
register_instance_option :thumb_method do
|
|
19
|
+
nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
register_instance_option :delete_key do
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
register_instance_option :pretty_value do
|
|
27
|
+
if value.presence
|
|
28
|
+
v = bindings[:view]
|
|
29
|
+
url = resource_url
|
|
30
|
+
if image
|
|
31
|
+
thumb_url = resource_url(thumb_method)
|
|
32
|
+
image_html = v.image_tag(thumb_url, class: 'img-thumbnail')
|
|
33
|
+
url != thumb_url ? v.link_to(image_html, url, target: '_blank') : image_html
|
|
34
|
+
else
|
|
35
|
+
v.link_to(value, url, target: '_blank')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
register_instance_option :image? do
|
|
41
|
+
(url = resource_url.to_s) && url.split('.').last =~ /jpg|jpeg|png|gif|svg/i
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def resource_url(_thumb = false)
|
|
45
|
+
raise('not implemented')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def initialize(*args)
|
|
50
|
+
super
|
|
51
|
+
@attachment_configurations = []
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
register_instance_option :attachment_class do
|
|
55
|
+
AbstractAttachment
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
register_instance_option :partial do
|
|
59
|
+
:form_multiple_file_upload
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
register_instance_option :cache_method do
|
|
63
|
+
nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
register_instance_option :delete_method do
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
register_instance_option :export_value do
|
|
71
|
+
attachments.map(&:resource_url).map(&:to_s).join(',')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
register_instance_option :pretty_value do
|
|
75
|
+
bindings[:view].safe_join attachments.map(&:pretty_value), ' '
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
register_instance_option :allowed_methods do
|
|
79
|
+
[method_name, cache_method, delete_method].compact
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
register_instance_option :html_attributes do
|
|
83
|
+
{
|
|
84
|
+
required: required? && !value.present?,
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def attachment(&block)
|
|
89
|
+
@attachment_configurations << block
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def attachments
|
|
93
|
+
Array(value).map do |attached|
|
|
94
|
+
attachment = attachment_class.new(attached)
|
|
95
|
+
@attachment_configurations.each do |config|
|
|
96
|
+
attachment.instance_eval(&config)
|
|
97
|
+
end
|
|
98
|
+
attachment.with(bindings)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# virtual class
|
|
103
|
+
def virtual?
|
|
104
|
+
true
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -130,7 +130,7 @@ module RailsAdmin
|
|
|
130
130
|
@_ro_fields = @_fields = RailsAdmin::Config::Fields.factory(self)
|
|
131
131
|
else
|
|
132
132
|
# parent is RailsAdmin::Config::Model, recursion is on Section's classes
|
|
133
|
-
@_ro_fields ||= parent.send(self.class.superclass.to_s.underscore.split('/').last)._fields(true).freeze
|
|
133
|
+
@_ro_fields ||= parent.send(self.class.superclass.to_s.underscore.split('/').last)._fields(true).clone.freeze
|
|
134
134
|
end
|
|
135
135
|
readonly ? @_ro_fields : (@_fields ||= @_ro_fields.collect(&:clone))
|
|
136
136
|
end
|
data/lib/rails_admin/engine.rb
CHANGED
|
@@ -24,10 +24,26 @@ module RailsAdmin
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
initializer 'RailsAdmin setup middlewares' do |app|
|
|
27
|
+
app.config.session_store :cookie_store
|
|
28
|
+
app.config.middleware.use ActionDispatch::Cookies
|
|
27
29
|
app.config.middleware.use ActionDispatch::Flash
|
|
30
|
+
app.config.middleware.use ActionDispatch::Session::CookieStore, app.config.session_options
|
|
31
|
+
app.config.middleware.use Rack::MethodOverride
|
|
28
32
|
app.config.middleware.use Rack::Pjax
|
|
29
33
|
end
|
|
30
34
|
|
|
35
|
+
initializer 'RailsAdmin reload config in development' do
|
|
36
|
+
if Rails.application.config.cache_classes
|
|
37
|
+
if defined?(ActiveSupport::Reloader)
|
|
38
|
+
ActiveSupport::Reloader.before_class_unload do
|
|
39
|
+
RailsAdmin::Config.reset_all_models
|
|
40
|
+
end
|
|
41
|
+
# else
|
|
42
|
+
# For Rails 4 not implemented
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
31
47
|
rake_tasks do
|
|
32
48
|
Dir[File.join(File.dirname(__FILE__), '../tasks/*.rake')].each { |f| load f }
|
|
33
49
|
end
|
|
@@ -2,51 +2,43 @@ module RailsAdmin
|
|
|
2
2
|
module Extensions
|
|
3
3
|
module CanCanCan
|
|
4
4
|
# This adapter is for the CanCanCan[https://github.com/CanCanCommunity/cancancan] authorization library.
|
|
5
|
-
class AuthorizationAdapter
|
|
6
|
-
# See the +authorize_with+ config method for where the initialization happens.
|
|
7
|
-
def initialize(controller, ability = ::Ability)
|
|
8
|
-
@controller = controller
|
|
9
|
-
@controller.instance_variable_set '@ability', ability
|
|
10
|
-
@controller.extend ControllerExtension
|
|
11
|
-
@controller.current_ability.authorize! :access, :rails_admin
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
# This method is called in every controller action and should raise an exception
|
|
15
|
-
# when the authorization fails. The first argument is the name of the controller
|
|
16
|
-
# action as a symbol (:create, :bulk_delete, etc.). The second argument is the
|
|
17
|
-
# AbstractModel instance that applies. The third argument is the actual model
|
|
18
|
-
# instance if it is available.
|
|
5
|
+
class AuthorizationAdapter < RailsAdmin::Extensions::CanCan::AuthorizationAdapter
|
|
19
6
|
def authorize(action, abstract_model = nil, model_object = nil)
|
|
20
|
-
|
|
7
|
+
return unless action
|
|
8
|
+
subject = model_object || abstract_model && abstract_model.model
|
|
9
|
+
if authorized_for_dashboard_in_legacy_way?(action)
|
|
10
|
+
subject
|
|
11
|
+
else
|
|
12
|
+
@controller.current_ability.authorize!(*resolve_with_compatibility(action, subject))
|
|
13
|
+
end
|
|
21
14
|
end
|
|
22
15
|
|
|
23
|
-
# This method is called primarily from the view to determine whether the given user
|
|
24
|
-
# has access to perform the action on a given model. It should return true when authorized.
|
|
25
|
-
# This takes the same arguments as +authorize+. The difference is that this will
|
|
26
|
-
# return a boolean whereas +authorize+ will raise an exception when not authorized.
|
|
27
16
|
def authorized?(action, abstract_model = nil, model_object = nil)
|
|
28
|
-
|
|
17
|
+
return unless action
|
|
18
|
+
subject = model_object || abstract_model && abstract_model.model
|
|
19
|
+
authorized_for_dashboard_in_legacy_way?(action, true) ||
|
|
20
|
+
@controller.current_ability.can?(*resolve_with_compatibility(action, subject))
|
|
29
21
|
end
|
|
30
22
|
|
|
31
|
-
|
|
32
|
-
# and bulk_delete/destroy actions and should return a scope which limits the records
|
|
33
|
-
# to those which the user can perform the given action on.
|
|
34
|
-
def query(action, abstract_model)
|
|
35
|
-
abstract_model.model.accessible_by(@controller.current_ability, action)
|
|
36
|
-
end
|
|
23
|
+
private
|
|
37
24
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
def authorized_for_dashboard_in_legacy_way?(action, silent = false)
|
|
26
|
+
return false unless action == :dashboard
|
|
27
|
+
legacy_ability = @controller.current_ability.permissions[:can][:dashboard]
|
|
28
|
+
if legacy_ability && (legacy_ability.empty? || legacy_ability.all?(&:empty?))
|
|
29
|
+
ActiveSupport::Deprecation.warn('RailsAdmin CanCanCan Ability with `can :dashboard` is old and support will be removed in the next major release, use `can :read, :dashboard` instead. See https://github.com/sferik/rails_admin/issues/2901') unless silent
|
|
30
|
+
true
|
|
31
|
+
else
|
|
32
|
+
false
|
|
33
|
+
end
|
|
43
34
|
end
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
def resolve_with_compatibility(action, subject)
|
|
37
|
+
if subject
|
|
38
|
+
[action, subject]
|
|
39
|
+
else
|
|
40
|
+
# For :dashboard compatibility
|
|
41
|
+
[:read, action]
|
|
50
42
|
end
|
|
51
43
|
end
|
|
52
44
|
end
|
|
@@ -43,7 +43,7 @@ module RailsAdmin
|
|
|
43
43
|
# and bulk_delete/destroy actions and should return a scope which limits the records
|
|
44
44
|
# to those which the user can perform the given action on.
|
|
45
45
|
def query(_action, abstract_model)
|
|
46
|
-
@controller.policy_scope
|
|
46
|
+
@controller.send(:policy_scope, abstract_model.model.all)
|
|
47
47
|
rescue ::Pundit::NotDefinedError
|
|
48
48
|
abstract_model.model.all
|
|
49
49
|
end
|
|
@@ -59,7 +59,7 @@ module RailsAdmin
|
|
|
59
59
|
private
|
|
60
60
|
|
|
61
61
|
def policy(record)
|
|
62
|
-
@controller.policy
|
|
62
|
+
@controller.send(:policy, record)
|
|
63
63
|
rescue ::Pundit::NotDefinedError
|
|
64
64
|
::ApplicationPolicy.new(@controller.send(:pundit_user), record)
|
|
65
65
|
end
|
data/lib/rails_admin/version.rb
CHANGED
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: 1.
|
|
4
|
+
version: 1.4.0
|
|
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: 2018-
|
|
15
|
+
date: 2018-07-22 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: builder
|
|
@@ -106,16 +106,22 @@ dependencies:
|
|
|
106
106
|
name: jquery-ui-rails
|
|
107
107
|
requirement: !ruby/object:Gem::Requirement
|
|
108
108
|
requirements:
|
|
109
|
-
- - "
|
|
109
|
+
- - ">="
|
|
110
110
|
- !ruby/object:Gem::Version
|
|
111
111
|
version: '5.0'
|
|
112
|
+
- - "<"
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '7'
|
|
112
115
|
type: :runtime
|
|
113
116
|
prerelease: false
|
|
114
117
|
version_requirements: !ruby/object:Gem::Requirement
|
|
115
118
|
requirements:
|
|
116
|
-
- - "
|
|
119
|
+
- - ">="
|
|
117
120
|
- !ruby/object:Gem::Version
|
|
118
121
|
version: '5.0'
|
|
122
|
+
- - "<"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '7'
|
|
119
125
|
- !ruby/object:Gem::Dependency
|
|
120
126
|
name: kaminari
|
|
121
127
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -305,6 +311,7 @@ files:
|
|
|
305
311
|
- app/assets/javascripts/rails_admin/bootstrap/bootstrap-typeahead.js
|
|
306
312
|
- app/assets/javascripts/rails_admin/bootstrap/bootstrap.js
|
|
307
313
|
- app/assets/javascripts/rails_admin/custom/ui.coffee
|
|
314
|
+
- app/assets/javascripts/rails_admin/jquery-ui.js.erb
|
|
308
315
|
- app/assets/javascripts/rails_admin/jquery.colorpicker.js
|
|
309
316
|
- app/assets/javascripts/rails_admin/jquery.pjax.js
|
|
310
317
|
- app/assets/javascripts/rails_admin/ra.filter-box.js
|
|
@@ -442,6 +449,7 @@ files:
|
|
|
442
449
|
- app/views/rails_admin/main/_form_filtering_multiselect.html.haml
|
|
443
450
|
- app/views/rails_admin/main/_form_filtering_select.html.haml
|
|
444
451
|
- app/views/rails_admin/main/_form_froala.html.haml
|
|
452
|
+
- app/views/rails_admin/main/_form_multiple_file_upload.html.haml
|
|
445
453
|
- app/views/rails_admin/main/_form_nested_many.html.haml
|
|
446
454
|
- app/views/rails_admin/main/_form_nested_one.html.haml
|
|
447
455
|
- app/views/rails_admin/main/_form_polymorphic_association.html.haml
|
|
@@ -500,6 +508,7 @@ files:
|
|
|
500
508
|
- lib/rails_admin/config/fields.rb
|
|
501
509
|
- lib/rails_admin/config/fields/association.rb
|
|
502
510
|
- lib/rails_admin/config/fields/base.rb
|
|
511
|
+
- lib/rails_admin/config/fields/factories/active_storage.rb
|
|
503
512
|
- lib/rails_admin/config/fields/factories/association.rb
|
|
504
513
|
- lib/rails_admin/config/fields/factories/carrierwave.rb
|
|
505
514
|
- lib/rails_admin/config/fields/factories/devise.rb
|
|
@@ -511,6 +520,7 @@ files:
|
|
|
511
520
|
- lib/rails_admin/config/fields/group.rb
|
|
512
521
|
- lib/rails_admin/config/fields/types.rb
|
|
513
522
|
- lib/rails_admin/config/fields/types/active_record_enum.rb
|
|
523
|
+
- lib/rails_admin/config/fields/types/active_storage.rb
|
|
514
524
|
- lib/rails_admin/config/fields/types/all.rb
|
|
515
525
|
- lib/rails_admin/config/fields/types/belongs_to_association.rb
|
|
516
526
|
- lib/rails_admin/config/fields/types/boolean.rb
|
|
@@ -534,6 +544,9 @@ files:
|
|
|
534
544
|
- lib/rails_admin/config/fields/types/inet.rb
|
|
535
545
|
- lib/rails_admin/config/fields/types/integer.rb
|
|
536
546
|
- lib/rails_admin/config/fields/types/json.rb
|
|
547
|
+
- lib/rails_admin/config/fields/types/multiple_active_storage.rb
|
|
548
|
+
- lib/rails_admin/config/fields/types/multiple_carrierwave.rb
|
|
549
|
+
- lib/rails_admin/config/fields/types/multiple_file_upload.rb
|
|
537
550
|
- lib/rails_admin/config/fields/types/paperclip.rb
|
|
538
551
|
- lib/rails_admin/config/fields/types/password.rb
|
|
539
552
|
- lib/rails_admin/config/fields/types/polymorphic_association.rb
|