slash_admin 0.1.0 → 1.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/README.md +38 -12
- data/app/assets/images/slash_admin/favicon.png +0 -0
- data/app/assets/images/slash_admin/logo.png +0 -0
- data/app/assets/javascripts/slash_admin/application.js +33 -25
- data/app/assets/stylesheets/slash_admin/application.scss +271 -146
- data/app/assets/stylesheets/slash_admin/colors.scss +16 -13
- data/app/controllers/slash_admin/models_controller.rb +166 -32
- data/app/controllers/slash_admin/security/sessions_controller.rb +1 -1
- data/app/controllers/slash_admin/selectize_controller.rb +21 -1
- data/app/helpers/slash_admin/application_helper.rb +45 -4
- data/app/helpers/slash_admin/widgets_helper.rb +1 -0
- data/app/views/layouts/slash_admin/application.html.erb +1 -1
- data/app/views/slash_admin/base/_data_belongs_to.html.erb +14 -16
- data/app/views/slash_admin/base/_data_list.html.erb +118 -121
- data/app/views/slash_admin/base/_data_nestable.html.erb +2 -2
- data/app/views/slash_admin/base/_data_new.html.erb +4 -1
- data/app/views/slash_admin/base/_filters.html.erb +63 -55
- data/app/views/slash_admin/base/index.html.erb +3 -3
- data/app/views/slash_admin/custom_fields/_google_map.html.erb +14 -11
- data/app/views/slash_admin/custom_fields/_select.html.erb +5 -1
- data/app/views/slash_admin/custom_fields/_timezone.html.erb +2 -0
- data/app/views/slash_admin/dashboard/widgets/_statistic_progress_tile.html.erb +1 -1
- data/app/views/slash_admin/fields/_belongs_to.html.erb +2 -2
- data/app/views/slash_admin/fields/_carrierwave.html.erb +107 -10
- data/app/views/slash_admin/fields/_has_many.html.erb +2 -2
- data/app/views/slash_admin/fields/_has_one.html.erb +9 -24
- data/app/views/slash_admin/fields/_json.html.erb +1 -1
- data/app/views/slash_admin/fields/_jsonb.html.erb +14 -0
- data/app/views/slash_admin/{custom_fields → fields}/_nested_belongs_to.html.erb +11 -10
- data/app/views/slash_admin/fields/_nested_has_one.html.erb +23 -0
- data/app/views/slash_admin/security/sessions/new.html.erb +6 -3
- data/app/views/slash_admin/shared/_batch_actions.html.erb +1 -1
- data/app/views/slash_admin/shared/_header.html.erb +2 -3
- data/app/views/slash_admin/shared/_menu.html.erb +33 -30
- data/app/views/slash_admin/shared/_new_form_buttons.html.erb +2 -2
- data/config/initializers/validators.rb +4 -0
- data/config/locales/{slash_admin.en.yml → en.yml} +3 -0
- data/config/locales/{slash_admin.fr.yml → fr.yml} +4 -1
- data/lib/batch_translation.rb +1 -1
- data/lib/generators/slash_admin/override_admin/override_admin_generator.rb +1 -0
- data/lib/generators/slash_admin/override_session/templates/session.erb +2 -2
- data/lib/slash_admin.rb +1 -3
- data/lib/slash_admin/version.rb +1 -1
- data/vendor/assets/javascripts/bootstrap-datepicker.fr.min.js +1 -0
- data/vendor/assets/javascripts/bootstrap-datepicker.min.js +8 -0
- data/vendor/assets/stylesheets/bootstrap-datepicker.min.css +7 -0
- metadata +19 -69
@@ -1,17 +1,20 @@
|
|
1
1
|
// Bootstrap override
|
2
|
-
$blue: #
|
3
|
-
$yellow: #
|
4
|
-
$green: #
|
5
|
-
$red: #
|
2
|
+
$blue: #6798ff !default;
|
3
|
+
$yellow: #fad961 !default;
|
4
|
+
$green: #57ca85 !default;
|
5
|
+
$red: #F36265 !default;
|
6
|
+
$pink: #ff3466 !default;
|
6
7
|
|
7
|
-
$
|
8
|
-
$
|
9
|
-
$
|
10
|
-
$
|
8
|
+
$info: #6798ff;
|
9
|
+
$notice: #fad961;
|
10
|
+
$success: #57ca85;
|
11
|
+
$error: #F36265;
|
11
12
|
|
12
|
-
|
13
|
-
$
|
14
|
-
$secondary: #
|
15
|
-
$
|
16
|
-
$
|
13
|
+
$primary: #2e5bff;
|
14
|
+
$blueIcon: #9ddbff;
|
15
|
+
$secondary: #120731;
|
16
|
+
$sidebar: #33375b;
|
17
|
+
$textColor: #c5a6ee;
|
18
|
+
$tertiary: #f8f8fd;
|
19
|
+
$grey: #7985A6;
|
17
20
|
$lightgrey: #e1e5ec;
|
@@ -2,6 +2,7 @@ require 'csv'
|
|
2
2
|
|
3
3
|
module SlashAdmin
|
4
4
|
class ModelsController < SlashAdmin::BaseController
|
5
|
+
skip_before_action :verify_authenticity_token, only: :nestable
|
5
6
|
before_action :handle_internal_default
|
6
7
|
before_action :handle_default
|
7
8
|
before_action :nestable_config
|
@@ -21,7 +22,16 @@ module SlashAdmin
|
|
21
22
|
column = @model_class.arel_table[params[:order_field].to_sym]
|
22
23
|
order = params[:order].downcase
|
23
24
|
if %w(asc desc).include?(order)
|
24
|
-
|
25
|
+
if @models_export.is_a? Array
|
26
|
+
if order == 'asc'
|
27
|
+
@models = @models_export.sort { |m1, m2| m1.send(params[:order_field]) <=> m2.send(params[:order_field]) }
|
28
|
+
else
|
29
|
+
@models = @models_export.sort { |m1, m2| m2.send(params[:order_field]) <=> m1.send(params[:order_field]) }
|
30
|
+
end
|
31
|
+
@models = Kaminari.paginate_array(@models).page(params[:page]).per(params[:per])
|
32
|
+
else
|
33
|
+
@models = @models_export.order(column.send(params[:order].downcase)).page(params[:page]).per(params[:per])
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
@fields = if @use_export_params
|
@@ -32,8 +42,8 @@ module SlashAdmin
|
|
32
42
|
|
33
43
|
respond_to do |format|
|
34
44
|
format.html
|
35
|
-
format.csv {
|
36
|
-
format.xls { send_data render_to_string, filename: "#{@model_name.
|
45
|
+
format.csv { stream_csv_report }
|
46
|
+
format.xls { send_data render_to_string, filename: "#{@model_class.model_name.plural.upcase}_#{Date.today}.xls" }
|
37
47
|
format.js { @models }
|
38
48
|
end
|
39
49
|
end
|
@@ -44,25 +54,31 @@ module SlashAdmin
|
|
44
54
|
end
|
45
55
|
|
46
56
|
def before_validate_on_create; end
|
57
|
+
def after_save_on_create; end
|
47
58
|
def create
|
48
59
|
authorize! :new, @model_class
|
60
|
+
handle_has_one
|
61
|
+
|
49
62
|
@model = @model_class.new(permit_params)
|
50
63
|
|
51
64
|
before_validate_on_create
|
65
|
+
handle_specific_fields
|
52
66
|
|
53
67
|
if @model.valid?
|
54
68
|
if @model.save!
|
69
|
+
after_save_on_create
|
55
70
|
respond_to do |format|
|
56
71
|
format.html do
|
57
72
|
flash[:success] = t('slash_admin.controller.create.success', model_name: @model_name)
|
58
73
|
redirect_to handle_redirect_after_submit and return
|
59
74
|
end
|
60
|
-
format.js { render json: @model and return }
|
75
|
+
format.js { render json: { id: @model.id, name: helpers.show_object(@model) } and return }
|
61
76
|
end
|
62
77
|
end
|
63
78
|
else
|
64
79
|
flash[:error] = t('slash_admin.controller.create.error', model_name: @model_name)
|
65
80
|
end
|
81
|
+
|
66
82
|
respond_to do |format|
|
67
83
|
format.html { render :new }
|
68
84
|
format.js { render json: { errors: @model.errors.full_messages } }
|
@@ -74,23 +90,30 @@ module SlashAdmin
|
|
74
90
|
@model = @model_class.find(params[:id])
|
75
91
|
end
|
76
92
|
|
77
|
-
def before_validate_on_update; end
|
78
93
|
def update
|
79
94
|
authorize! :edit, @model_class
|
80
95
|
@model = @model_class.find(params[:id])
|
81
96
|
|
97
|
+
handle_has_one
|
98
|
+
|
99
|
+
@model.assign_attributes(permit_params)
|
100
|
+
|
82
101
|
before_validate_on_update
|
102
|
+
handle_specific_fields
|
83
103
|
|
84
|
-
if @model.
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
format
|
104
|
+
if @model.valid?
|
105
|
+
if @model.save!
|
106
|
+
after_save_on_update
|
107
|
+
flash[:success] = t('slash_admin.controller.update.success', model_name: @model_name)
|
108
|
+
respond_to do |format|
|
109
|
+
format.html { redirect_to handle_redirect_after_submit and return }
|
110
|
+
format.js
|
111
|
+
end
|
89
112
|
end
|
90
113
|
else
|
91
114
|
flash[:error] = t('slash_admin.controller.update.error', model_name: @model_name)
|
92
115
|
end
|
93
|
-
render :edit
|
116
|
+
render :edit
|
94
117
|
end
|
95
118
|
|
96
119
|
def show
|
@@ -112,6 +135,49 @@ module SlashAdmin
|
|
112
135
|
end
|
113
136
|
end
|
114
137
|
|
138
|
+
def before_validate_on_update; end
|
139
|
+
def after_save_on_update; end
|
140
|
+
|
141
|
+
def handle_has_one
|
142
|
+
@has_one = {}
|
143
|
+
Array.wrap(update_params + create_params).uniq.each do |p|
|
144
|
+
if helpers.guess_field_type(@model_class.new, p) == 'has_one' && !@model_class.nested_attributes_options.key?(p.to_sym)
|
145
|
+
@has_one[p] = permit_params[p]
|
146
|
+
permit_params.delete(p)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def handle_specific_fields
|
152
|
+
# has_one
|
153
|
+
if @has_one.present?
|
154
|
+
@has_one.each do |k, v|
|
155
|
+
if v.present?
|
156
|
+
@model.send("#{k}=", helpers.class_name_from_association(@model, k).constantize.find(v))
|
157
|
+
else
|
158
|
+
@model.send("#{k}=", nil)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# JSON
|
164
|
+
@model_class.columns_hash.each do |k, v|
|
165
|
+
if permit_params[k].is_a? String
|
166
|
+
if v.type == :json || v.type == :jsonb || helpers.serialized_json_field?(@model_class, k.to_s)
|
167
|
+
begin
|
168
|
+
@model.send("#{k}=", JSON.parse(permit_params[k]))
|
169
|
+
rescue
|
170
|
+
# Handle case when single string passed, we transform it into array to have a valid json
|
171
|
+
json = permit_params[k].split(',').to_json
|
172
|
+
@model.send("#{k}=", JSON.parse(json))
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# Other
|
179
|
+
end
|
180
|
+
|
115
181
|
def nestable
|
116
182
|
unless @is_nestable
|
117
183
|
flash[:error] = t('slash_admin.controller.nestable.error', model_name: @model_name)
|
@@ -135,16 +201,39 @@ module SlashAdmin
|
|
135
201
|
end
|
136
202
|
|
137
203
|
def handle_filtered_search
|
138
|
-
|
204
|
+
if @model_class.respond_to? :translated_attribute_names
|
205
|
+
search = @model_class.with_translations(I18n.locale).all
|
206
|
+
else
|
207
|
+
search = @model_class.all
|
208
|
+
end
|
209
|
+
|
210
|
+
virtual_fields = []
|
139
211
|
|
140
212
|
params[:filters].each do |attr, query|
|
141
213
|
unless query.blank?
|
142
|
-
|
143
|
-
|
214
|
+
attr_type = helpers.guess_field_type(@model_class, attr)
|
215
|
+
if @model_class.respond_to?(:translated_attribute_names) && @model_class.translated_attribute_names.include?(attr.to_sym)
|
216
|
+
attr = "#{@model_class.name.singularize.underscore}_translations.#{attr}"
|
217
|
+
end
|
218
|
+
case attr_type
|
219
|
+
when 'belongs_to'
|
220
|
+
search = search.eager_load(attr.to_s)
|
221
|
+
search = search.where(attr.to_s + '_id IN (' + query.join(',') + ')')
|
222
|
+
when 'has_one'
|
223
|
+
search = search.eager_load(attr.to_s)
|
224
|
+
search = search.where(attr.to_s.pluralize + '.id IN (' + query.join(',') + ')')
|
144
225
|
when 'string', 'text'
|
145
|
-
|
146
|
-
|
147
|
-
|
226
|
+
query.strip! unless query.strip!.nil?
|
227
|
+
attributes = @model_class.new.attributes.keys
|
228
|
+
if !attributes.include?(attr.to_s) && @model_class.method_defined?(attr.to_s)
|
229
|
+
virtual_fields << attr.to_s
|
230
|
+
else
|
231
|
+
begin
|
232
|
+
search = search.where("unaccent(lower(#{attr})) LIKE unaccent(lower(:query))", query: "%#{query}%")
|
233
|
+
rescue
|
234
|
+
search = search.where("lower(#{attr}) LIKE lower(:query)", query: "%#{query}%")
|
235
|
+
end
|
236
|
+
end
|
148
237
|
when 'date', 'datetime'
|
149
238
|
if query.is_a?(String)
|
150
239
|
search = search.where("#{attr} = :query", query: query)
|
@@ -163,12 +252,31 @@ module SlashAdmin
|
|
163
252
|
end
|
164
253
|
end
|
165
254
|
when 'decimal', 'number', 'integer'
|
166
|
-
|
167
|
-
|
255
|
+
if query.instance_of?(ActionController::Parameters)
|
256
|
+
if query['from'].present? || query['to'].present?
|
257
|
+
search = search.where("#{attr} >= :query", query: query['from']) if query['from'].present?
|
258
|
+
search = search.where("#{attr} <= :query", query: query['to']) if query['to'].present?
|
259
|
+
end
|
260
|
+
else
|
261
|
+
if attr_type == 'decimal' || attr_type == 'number'
|
262
|
+
query = query.to_f
|
263
|
+
elsif attr_type == 'integer'
|
264
|
+
query = query.to_i
|
265
|
+
end
|
266
|
+
search = search.where("#{attr} = :query", query: query)
|
267
|
+
end
|
168
268
|
when 'boolean'
|
169
269
|
search = search.where("#{attr} = :query", query: to_boolean(query))
|
170
|
-
|
171
|
-
|
270
|
+
else
|
271
|
+
raise Exception.new("Unable to query for attribute_type : #{attr_type}")
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
params[:filters].each do |attr, query|
|
277
|
+
unless query.blank?
|
278
|
+
if virtual_fields.present? && virtual_fields.include?(attr.to_s)
|
279
|
+
search = search.select { |s| s.send(attr).present? ? s.send(attr).downcase.include?(query.downcase) : nil }
|
172
280
|
end
|
173
281
|
end
|
174
282
|
end
|
@@ -178,14 +286,7 @@ module SlashAdmin
|
|
178
286
|
|
179
287
|
# Export CSV
|
180
288
|
def export_csv(options = {})
|
181
|
-
|
182
|
-
header = @fields.map { |f| @model_class.human_attribute_name(f) }
|
183
|
-
csv << header
|
184
|
-
@models_export.each do |m|
|
185
|
-
csv << m.attributes.values_at(*@fields)
|
186
|
-
end
|
187
|
-
csv
|
188
|
-
end
|
289
|
+
@models_export.to_sql
|
189
290
|
end
|
190
291
|
|
191
292
|
def update_params(options = {})
|
@@ -228,9 +329,9 @@ module SlashAdmin
|
|
228
329
|
def handle_default
|
229
330
|
@title = @model_name.present? ? @model_class.model_name.human(count: 2) : nil
|
230
331
|
@sub_title = nil
|
231
|
-
@per =
|
332
|
+
@per = 20
|
232
333
|
@page = 1
|
233
|
-
@per_values = [
|
334
|
+
@per_values = [20, 30, 50, 100, 150]
|
234
335
|
@use_export_params = false
|
235
336
|
@order_field = :id
|
236
337
|
@order = 'DESC'
|
@@ -312,7 +413,31 @@ module SlashAdmin
|
|
312
413
|
|
313
414
|
# Exclude default params for edit and create
|
314
415
|
def exclude_default_params(params)
|
315
|
-
params - %w(id created_at updated_at slug position)
|
416
|
+
params = params - %w(id created_at updated_at slug position)
|
417
|
+
if @model_class.try(:translated_attribute_names).present?
|
418
|
+
params = params - @model_class.translated_attribute_names.map(&:to_s)
|
419
|
+
end
|
420
|
+
params
|
421
|
+
end
|
422
|
+
|
423
|
+
def stream_file(filename, extension)
|
424
|
+
response.headers['Content-Type'] = 'application/octet-stream'
|
425
|
+
response.headers['Content-Disposition'] = "attachment; filename=#{filename}.#{extension}"
|
426
|
+
|
427
|
+
yield response.stream
|
428
|
+
ensure
|
429
|
+
response.stream.close
|
430
|
+
end
|
431
|
+
|
432
|
+
def stream_csv_report
|
433
|
+
query = @models_export.limit(5000).to_sql
|
434
|
+
query_options = 'WITH CSV HEADER'
|
435
|
+
|
436
|
+
stream_file("#{@model_class.model_name.plural.upcase}_#{Date.today}", 'csv') do |stream|
|
437
|
+
stream_query_rows(query, query_options) do |row_from_db|
|
438
|
+
stream.write row_from_db
|
439
|
+
end
|
440
|
+
end
|
316
441
|
end
|
317
442
|
|
318
443
|
private
|
@@ -321,5 +446,14 @@ module SlashAdmin
|
|
321
446
|
def export_params
|
322
447
|
list_params
|
323
448
|
end
|
449
|
+
|
450
|
+
def stream_query_rows(sql_query, options = 'WITH CSV HEADER')
|
451
|
+
conn = ActiveRecord::Base.connection.raw_connection
|
452
|
+
conn.copy_data "COPY (#{sql_query}) TO STDOUT #{options};" do
|
453
|
+
while row = conn.get_copy_data
|
454
|
+
yield row
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
324
458
|
end
|
325
459
|
end
|
@@ -12,7 +12,7 @@ module SlashAdmin
|
|
12
12
|
admin = Admin.where('username = :value OR lower(email) = lower(:value)', value: params[:admin][:login]).first
|
13
13
|
if admin&.authenticate(params[:admin][:password])
|
14
14
|
session[:admin_id] = admin.id
|
15
|
-
flash[:
|
15
|
+
flash[:success] = 'Vous êtes à présent connecté.'
|
16
16
|
redirect_to slash_admin.dashboard_path
|
17
17
|
else
|
18
18
|
@error_messages = 'Merci de vérifier vos identifiants'
|
@@ -16,20 +16,40 @@ module SlashAdmin
|
|
16
16
|
|
17
17
|
duplicate_for_orwhere = results
|
18
18
|
|
19
|
+
virtual_fields = []
|
20
|
+
|
19
21
|
params[:fields].each_with_index do |f, index|
|
20
22
|
if model_class.respond_to? :translated_attribute_names
|
21
23
|
if model_class.translated_attribute_names.include?(f.to_sym)
|
22
24
|
f = "#{params[:model_class].singularize.underscore}_translations.#{f}"
|
23
25
|
end
|
26
|
+
else
|
27
|
+
unless model_class.column_names.include?(f) || model_class.respond_to?(f)
|
28
|
+
raise Exception.new("Unable to find attribute: #{f} in model_column: #{model_class}, you may need to override autocomplete_params in you target's model controller")
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
32
|
if index == 0
|
27
|
-
|
33
|
+
if model_class.column_names.include?(f)
|
34
|
+
results = results.where("lower(#{f}) LIKE lower(:query)", query: "%#{params[:q]}%")
|
35
|
+
else
|
36
|
+
virtual_fields << f
|
37
|
+
end
|
28
38
|
else
|
29
39
|
results = results.or(duplicate_for_orwhere.where("lower(#{f}) LIKE lower(:query)", query: "%#{params[:q]}%"))
|
30
40
|
end
|
31
41
|
end
|
32
42
|
|
43
|
+
params[:fields].each do |f|
|
44
|
+
unless params[:q].blank?
|
45
|
+
if virtual_fields.present? && virtual_fields.include?(f)
|
46
|
+
results = results.select { |s| s.send(f).present? ? s.send(f).downcase.include?(params[:q].downcase) : nil }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
33
53
|
formatted_result = []
|
34
54
|
results.each do |r|
|
35
55
|
formatted_result << { id: r.id, name: helpers.show_object(r) }
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module SlashAdmin
|
3
4
|
module ApplicationHelper
|
4
5
|
def page_title(content)
|
@@ -18,10 +19,17 @@ module SlashAdmin
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
# Direct Link temp TODO
|
22
22
|
if s[:path].present?
|
23
|
-
|
23
|
+
if can? s[:role], s[:role]
|
24
|
+
access = true
|
25
|
+
end
|
26
|
+
if s[:role].present?
|
27
|
+
if can? s[:role], s[:role]
|
28
|
+
access = true
|
29
|
+
end
|
30
|
+
end
|
24
31
|
end
|
32
|
+
|
25
33
|
access
|
26
34
|
end
|
27
35
|
|
@@ -79,6 +87,7 @@ module SlashAdmin
|
|
79
87
|
return true unless object.errors.messages[field_name].blank?
|
80
88
|
end
|
81
89
|
|
90
|
+
# Type must be 'warning' or 'success' or 'error'
|
82
91
|
def toastr_bootstrap
|
83
92
|
flash_messages = []
|
84
93
|
flash.each do |type, message|
|
@@ -150,6 +159,8 @@ module SlashAdmin
|
|
150
159
|
has_many_fields = object_class.reflect_on_all_associations(:has_many).map(&:name)
|
151
160
|
has_one_fields = object_class.reflect_on_all_associations(:has_one).map(&:name)
|
152
161
|
|
162
|
+
return if attr.is_a? Hash
|
163
|
+
|
153
164
|
type = if object_class&.uploaders&.key?(attr.to_sym)
|
154
165
|
'image'
|
155
166
|
elsif belongs_to_fields.include?(attr.to_sym)
|
@@ -170,6 +181,28 @@ module SlashAdmin
|
|
170
181
|
type
|
171
182
|
end
|
172
183
|
|
184
|
+
# From shoulda-matchers https://github.com/thoughtbot/shoulda-matchers/blob/da4e6ddd06de54016e7c2afd953120f0f6529c70/lib/shoulda/matchers/rails_shim.rb
|
185
|
+
# @param model @model_class
|
186
|
+
def serialized_attributes_for(model)
|
187
|
+
serialized_columns = model.columns.select do |column|
|
188
|
+
model.type_for_attribute(column.name).is_a?(
|
189
|
+
::ActiveRecord::Type::Serialized,
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
serialized_columns.inject({}) do |hash, column|
|
194
|
+
hash[column.name.to_s] = model.type_for_attribute(column.name).coder
|
195
|
+
hash
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# @param model @model_class
|
200
|
+
# @param attribute String
|
201
|
+
def serialized_json_field?(model, attribute)
|
202
|
+
hash = serialized_attributes_for(model)
|
203
|
+
hash.key?(attribute) && hash[attribute] == ::ActiveRecord::Coders::JSON
|
204
|
+
end
|
205
|
+
|
173
206
|
def admin_custom_field(form, attribute)
|
174
207
|
type = attribute[attribute.keys.first][:type].to_s
|
175
208
|
render partial: "slash_admin/custom_fields/#{type}", locals: { f: form, a: attribute }
|
@@ -186,7 +219,11 @@ module SlashAdmin
|
|
186
219
|
if attribute.is_a?(Hash)
|
187
220
|
admin_custom_field(form, attribute)
|
188
221
|
elsif belongs_to_fields.include?(attribute.to_sym)
|
189
|
-
|
222
|
+
if form.object.class.nested_attributes_options.key?(attribute.to_sym)
|
223
|
+
render partial: 'slash_admin/fields/nested_belongs_to', locals: { f: form, a: attribute }
|
224
|
+
else
|
225
|
+
render partial: 'slash_admin/fields/belongs_to', locals: { f: form, a: attribute }
|
226
|
+
end
|
190
227
|
elsif has_many_fields.include?(attribute.to_sym)
|
191
228
|
# if has nested_attributes_options for has_many field
|
192
229
|
if form.object.class.nested_attributes_options.key?(attribute.to_sym)
|
@@ -195,7 +232,11 @@ module SlashAdmin
|
|
195
232
|
render partial: 'slash_admin/fields/has_many', locals: { f: form, a: attribute }
|
196
233
|
end
|
197
234
|
elsif has_one_fields.include?(attribute.to_sym)
|
198
|
-
|
235
|
+
if form.object.class.nested_attributes_options.key?(attribute.to_sym)
|
236
|
+
render partial: 'slash_admin/fields/nested_has_one', locals: { f: form, a: attribute }
|
237
|
+
else
|
238
|
+
render partial: 'slash_admin/fields/has_one', locals: { f: form, a: attribute }
|
239
|
+
end
|
199
240
|
elsif form.object.class&.uploaders&.key?(attribute.to_sym)
|
200
241
|
render partial: 'slash_admin/fields/carrierwave', locals: { f: form, a: attribute }
|
201
242
|
else
|