active_scaffold 3.5.5 → 3.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{CHANGELOG → CHANGELOG.rdoc} +75 -0
- data/README.md +21 -10
- data/app/assets/javascripts/active_scaffold.js.erb +0 -1
- data/app/assets/javascripts/jquery/active_scaffold.js +98 -7
- data/app/assets/stylesheets/active_scaffold_colors.scss +1 -1
- data/app/assets/stylesheets/active_scaffold_layout.css +52 -29
- data/app/views/active_scaffold_overrides/_base_form.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_form.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_form_association.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +3 -2
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +26 -10
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_list.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_list_header.html.erb +5 -7
- data/app/views/active_scaffold_overrides/_list_messages.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_list_record.html.erb +4 -5
- data/app/views/active_scaffold_overrides/_list_with_header.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_messages.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +4 -0
- data/app/views/active_scaffold_overrides/_render_field.js.erb +2 -1
- data/app/views/active_scaffold_overrides/_show_association_horizontal.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_show_columns.html.erb +2 -2
- data/app/views/active_scaffold_overrides/_show_horizontal_record.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_update_calculations.js.erb +1 -1
- data/app/views/active_scaffold_overrides/_update_column.js.erb +2 -2
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +2 -2
- data/app/views/active_scaffold_overrides/action_confirmation.html.erb +2 -2
- data/app/views/active_scaffold_overrides/delete.html.erb +2 -2
- data/app/views/active_scaffold_overrides/on_action_update.js.erb +16 -6
- data/app/views/active_scaffold_overrides/on_update.js.erb +1 -1
- data/app/views/active_scaffold_overrides/row.js.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +2 -2
- data/config/locales/de.yml +2 -1
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/fr.yml +2 -1
- data/config/locales/hu.yml +1 -0
- data/config/locales/ja.yml +1 -0
- data/config/locales/ru.yml +1 -0
- data/lib/active_scaffold.rb +19 -16
- data/lib/active_scaffold/actions/common_search.rb +11 -8
- data/lib/active_scaffold/actions/core.rb +91 -70
- data/lib/active_scaffold/actions/create.rb +28 -28
- data/lib/active_scaffold/actions/delete.rb +3 -3
- data/lib/active_scaffold/actions/field_search.rb +53 -43
- data/lib/active_scaffold/actions/list.rb +111 -27
- data/lib/active_scaffold/actions/nested.rb +65 -48
- data/lib/active_scaffold/actions/search.rb +1 -1
- data/lib/active_scaffold/actions/show.rb +4 -4
- data/lib/active_scaffold/actions/subform.rb +23 -22
- data/lib/active_scaffold/actions/update.rb +96 -77
- data/lib/active_scaffold/active_record_permissions.rb +2 -11
- data/lib/active_scaffold/attribute_params.rb +102 -94
- data/lib/active_scaffold/bridges.rb +8 -8
- data/lib/active_scaffold/bridges/active_storage.rb +6 -0
- data/lib/active_scaffold/bridges/active_storage/active_storage_bridge.rb +34 -0
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +54 -0
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +22 -0
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +36 -0
- data/lib/active_scaffold/bridges/bitfields.rb +2 -1
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +12 -15
- data/lib/active_scaffold/bridges/bitfields/list_ui.rb +19 -0
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +3 -12
- data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +2 -2
- data/lib/active_scaffold/bridges/chosen/helpers.rb +7 -6
- data/lib/active_scaffold/bridges/date_picker/ext.rb +0 -13
- data/lib/active_scaffold/bridges/date_picker/helper.rb +49 -44
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +10 -7
- data/lib/active_scaffold/bridges/paper_trail.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +3 -1
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +2 -2
- data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -17
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +20 -19
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -1
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +21 -4
- data/lib/active_scaffold/config/base.rb +133 -41
- data/lib/active_scaffold/config/core.rb +146 -18
- data/lib/active_scaffold/config/delete.rb +14 -1
- data/lib/active_scaffold/config/field_search.rb +7 -1
- data/lib/active_scaffold/config/form.rb +10 -1
- data/lib/active_scaffold/config/list.rb +39 -13
- data/lib/active_scaffold/config/mark.rb +4 -2
- data/lib/active_scaffold/config/nested.rb +16 -17
- data/lib/active_scaffold/config/search.rb +9 -0
- data/lib/active_scaffold/config/show.rb +4 -0
- data/lib/active_scaffold/config/update.rb +4 -0
- data/lib/active_scaffold/configurable.rb +14 -7
- data/lib/active_scaffold/constraints.rb +22 -20
- data/lib/active_scaffold/core.rb +67 -28
- data/lib/active_scaffold/data_structures/action_columns.rb +50 -59
- data/lib/active_scaffold/data_structures/action_link.rb +50 -20
- data/lib/active_scaffold/data_structures/action_links.rb +15 -13
- data/lib/active_scaffold/data_structures/association/abstract.rb +38 -15
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +2 -6
- data/lib/active_scaffold/data_structures/association/active_record.rb +6 -2
- data/lib/active_scaffold/data_structures/association/mongoid.rb +0 -3
- data/lib/active_scaffold/data_structures/column.rb +75 -66
- data/lib/active_scaffold/data_structures/columns.rb +3 -2
- data/lib/active_scaffold/data_structures/nested_info.rb +33 -19
- data/lib/active_scaffold/data_structures/set.rb +8 -0
- data/lib/active_scaffold/data_structures/sorting.rb +10 -2
- data/lib/active_scaffold/delayed_setup.rb +16 -5
- data/lib/active_scaffold/extensions/action_controller_rendering.rb +3 -2
- data/lib/active_scaffold/extensions/action_view_rendering.rb +93 -32
- data/lib/active_scaffold/extensions/cow_proxy.rb +95 -0
- data/lib/active_scaffold/extensions/ice_nine.rb +36 -0
- data/lib/active_scaffold/extensions/left_outer_joins.rb +8 -33
- data/lib/active_scaffold/extensions/localize.rb +3 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +6 -45
- data/lib/active_scaffold/extensions/to_label.rb +3 -2
- data/lib/active_scaffold/extensions/unsaved_record.rb +2 -4
- data/lib/active_scaffold/finder.rb +110 -77
- data/lib/active_scaffold/helpers/action_link_helpers.rb +62 -36
- data/lib/active_scaffold/helpers/association_helpers.rb +18 -16
- data/lib/active_scaffold/helpers/controller_helpers.rb +34 -10
- data/lib/active_scaffold/helpers/form_column_helpers.rb +196 -124
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/id_helpers.rb +6 -2
- data/lib/active_scaffold/helpers/list_column_helpers.rb +90 -57
- data/lib/active_scaffold/helpers/pagination_helpers.rb +2 -2
- data/lib/active_scaffold/helpers/search_column_helpers.rb +43 -41
- data/lib/active_scaffold/helpers/show_column_helpers.rb +3 -5
- data/lib/active_scaffold/helpers/view_helpers.rb +39 -36
- data/lib/active_scaffold/marked_model.rb +2 -2
- data/lib/active_scaffold/orm_checks.rb +3 -7
- data/lib/active_scaffold/paginator.rb +7 -7
- data/lib/active_scaffold/registry.rb +33 -0
- data/lib/active_scaffold/responds_to_parent.rb +8 -11
- data/lib/active_scaffold/tableless.rb +83 -67
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold/controller_generator.rb +2 -2
- data/lib/generators/active_scaffold/install_generator.rb +52 -4
- data/lib/generators/active_scaffold/resource_generator.rb +2 -2
- data/shoulda_macros/macros.rb +3 -1
- data/test/bridges/date_picker_test.rb +1 -2
- data/test/bridges/paperclip_test.rb +6 -6
- data/test/class_with_finder.rb +2 -2
- data/test/company.rb +4 -4
- data/test/config/create_test.rb +4 -2
- data/test/config/nested_test.rb +1 -1
- data/test/config/show_test.rb +1 -1
- data/test/config/update_test.rb +7 -6
- data/test/data_structures/action_columns_test.rb +2 -2
- data/test/data_structures/action_links_test.rb +1 -1
- data/test/data_structures/column_test.rb +3 -6
- data/test/data_structures/columns_test.rb +2 -2
- data/test/data_structures/sorting_test.rb +7 -0
- data/test/extensions/action_view_rendering_test.rb +20 -0
- data/test/extensions/active_record_test.rb +4 -4
- data/test/extensions/routing_mapper_test.rb +2 -2
- data/test/helpers/list_column_helpers_test.rb +3 -1
- data/test/misc/active_record_permissions_test.rb +3 -11
- data/test/misc/attribute_params_test.rb +12 -8
- data/test/misc/calculation_test.rb +1 -1
- data/test/misc/configurable_test.rb +10 -10
- data/test/misc/constraints_test.rb +3 -3
- data/test/misc/convert_numbers_format_test.rb +7 -3
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/parse_datetime_test.rb +3 -4
- data/test/misc/tableless_test.rb +14 -0
- data/test/mock_app/Rakefile +1 -1
- data/test/mock_app/app/assets/config/manifest.js +0 -0
- data/test/mock_app/app/controllers/cars_controller.rb +1 -0
- data/test/mock_app/app/controllers/people_controller.rb +5 -1
- data/test/mock_app/app/controllers/roles_controller.rb +4 -0
- data/test/mock_app/app/views/active_scaffold_overrides/_form.html.erb +2 -0
- data/test/mock_app/app/views/active_scaffold_overrides/list.html.erb +2 -0
- data/test/mock_app/app/views/people/_first_name_form_column.html.erb +2 -0
- data/test/mock_app/app/views/people/_form.html.erb +2 -0
- data/test/mock_app/app/views/people/list.html.erb +2 -0
- data/test/mock_app/config/application.rb +2 -1
- data/test/mock_app/config/boot.rb +1 -1
- data/test/mock_app/config/environment.rb +2 -2
- data/test/mock_app/config/routes.rb +4 -1
- data/test/mock_app/db/schema.rb +2 -0
- data/test/performance/list_cars_performance_test.rb +34 -0
- data/test/performance/list_people_performance_test.rb +31 -0
- data/test/performance_test_help.rb +3 -0
- data/test/test_helper.rb +12 -4
- metadata +71 -15
- data/app/assets/javascripts/prototype/rico_corner.js +0 -370
- data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +0 -7
@@ -57,7 +57,7 @@ module ActiveScaffold
|
|
57
57
|
|
58
58
|
def active_scaffold_human_condition_boolean(column, value)
|
59
59
|
attribute = column.active_record_class.human_attribute_name(column.name)
|
60
|
-
label = as_(ActiveScaffold::Core.column_type_cast(value, column.column) ? :true : :false)
|
60
|
+
label = as_(ActiveScaffold::Core.column_type_cast(value, column.column) ? :true : :false) # rubocop:disable Lint/BooleanSymbol
|
61
61
|
as_(:boolean, :scope => :human_conditions, :column => attribute, :value => label)
|
62
62
|
end
|
63
63
|
alias active_scaffold_human_condition_checkbox active_scaffold_human_condition_boolean
|
@@ -10,12 +10,16 @@ module ActiveScaffold
|
|
10
10
|
'as_' + id_from_controller(controller)
|
11
11
|
end
|
12
12
|
|
13
|
+
def nested?
|
14
|
+
false # will be overrided in AS controllers with helper_method
|
15
|
+
end
|
16
|
+
|
13
17
|
def nested_parent_id
|
14
18
|
nested_parent_record.id
|
15
19
|
end
|
16
20
|
|
17
|
-
def nested_id(controller =
|
18
|
-
"#{nested.parent_scaffold.controller_path}-#{nested_parent_id}-#{controller}" if nested?
|
21
|
+
def nested_id(controller = nil)
|
22
|
+
"#{nested.parent_scaffold.controller_path}-#{nested_parent_id}-#{controller || params[:parent_controller] || params[:controller]}" if nested?
|
19
23
|
end
|
20
24
|
|
21
25
|
def active_scaffold_id
|
@@ -10,8 +10,8 @@ module ActiveScaffold
|
|
10
10
|
else
|
11
11
|
value = nil
|
12
12
|
end
|
13
|
-
value = ' '.html_safe if value.nil? || value.blank? # fix for IE 6
|
14
|
-
|
13
|
+
value = ' '.html_safe if value.nil? || value.blank? # fix for IE 6 # rubocop:disable Rails/OutputSafety
|
14
|
+
value
|
15
15
|
rescue StandardError => e
|
16
16
|
logger.error "#{e.class.name}: #{e.message} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}, record: #{record.inspect}"
|
17
17
|
raise e
|
@@ -19,7 +19,7 @@ module ActiveScaffold
|
|
19
19
|
|
20
20
|
def get_column_method(record, column)
|
21
21
|
# check for an override helper
|
22
|
-
column.
|
22
|
+
ActiveScaffold::Registry.cache :column_methods, column.cache_key do
|
23
23
|
if (method = column_override(column))
|
24
24
|
# we only pass the record as the argument. we previously also passed the formatted_value,
|
25
25
|
# but mike perham pointed out that prohibited the usage of overrides to improve on the
|
@@ -47,8 +47,8 @@ module ActiveScaffold
|
|
47
47
|
render_action_link(link, record, :link => text, :authorized => authorized, :not_authorized_reason => reason)
|
48
48
|
elsif inplace_edit?(record, column)
|
49
49
|
active_scaffold_inplace_edit(record, column, :formatted_column => text)
|
50
|
-
elsif
|
51
|
-
content_tag
|
50
|
+
elsif column_wrap_tag
|
51
|
+
content_tag column_wrap_tag, text
|
52
52
|
else
|
53
53
|
text
|
54
54
|
end
|
@@ -57,6 +57,11 @@ module ActiveScaffold
|
|
57
57
|
raise e
|
58
58
|
end
|
59
59
|
|
60
|
+
def column_wrap_tag
|
61
|
+
return @_column_wrap_tag if defined? @_column_wrap_tag
|
62
|
+
@_column_wrap_tag = (active_scaffold_config.list.wrap_tag if active_scaffold_config.actions.include?(:list))
|
63
|
+
end
|
64
|
+
|
60
65
|
# There are two basic ways to clean a column's value: h() and sanitize(). The latter is useful
|
61
66
|
# when the column contains *valid* html data, and you want to just disable any scripting. People
|
62
67
|
# can always use field overrides to clean data one way or the other, but having this override
|
@@ -127,20 +132,21 @@ module ActiveScaffold
|
|
127
132
|
|
128
133
|
# the naming convention for overriding column types with helpers
|
129
134
|
def override_column_ui(list_ui)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
135
|
+
ActiveScaffold::Registry.cache :column_ui_overrides, list_ui do
|
136
|
+
method = "active_scaffold_column_#{list_ui}"
|
137
|
+
method if respond_to? method
|
138
|
+
end
|
134
139
|
end
|
135
140
|
alias override_column_ui? override_column_ui
|
136
141
|
|
137
142
|
##
|
138
143
|
## Formatting
|
139
144
|
##
|
145
|
+
FORM_UI_WITH_OPTIONS = %i[select radio].freeze
|
140
146
|
def format_column_value(record, column, value = nil)
|
141
147
|
value ||= record.send(column.name) unless record.nil?
|
142
148
|
if column.association.nil?
|
143
|
-
if
|
149
|
+
if FORM_UI_WITH_OPTIONS.include?(column.form_ui) && column.options[:options]
|
144
150
|
text, val = column.options[:options].find { |t, v| (v.nil? ? t : v).to_s == value.to_s }
|
145
151
|
value = active_scaffold_translated_option(column, text, val).first if text
|
146
152
|
end
|
@@ -153,7 +159,7 @@ module ActiveScaffold
|
|
153
159
|
end
|
154
160
|
else
|
155
161
|
if column.association.collection?
|
156
|
-
associated_size = value
|
162
|
+
associated_size = column_association_size(record, column, value) if column.associated_number? # get count before cache association
|
157
163
|
if column.association.respond_to_target? && !value.loaded?
|
158
164
|
cache_association(record.association(column.name), column, associated_size)
|
159
165
|
end
|
@@ -162,20 +168,31 @@ module ActiveScaffold
|
|
162
168
|
end
|
163
169
|
end
|
164
170
|
|
171
|
+
def column_association_size(record, column, value)
|
172
|
+
cached_counts = @counts&.dig(column.name)
|
173
|
+
if cached_counts
|
174
|
+
key = column.association.primary_key if count_on_association_class?(column)
|
175
|
+
cached_counts[record.send(key || :id)] || 0
|
176
|
+
else
|
177
|
+
value.size
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
165
181
|
def format_number_value(value, options = {})
|
166
182
|
if value
|
167
|
-
value =
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
183
|
+
value =
|
184
|
+
case options[:format]
|
185
|
+
when :size
|
186
|
+
number_to_human_size(value, options[:i18n_options] || {})
|
187
|
+
when :percentage
|
188
|
+
number_to_percentage(value, options[:i18n_options] || {})
|
189
|
+
when :currency
|
190
|
+
number_to_currency(value, options[:i18n_options] || {})
|
191
|
+
when :i18n_number
|
192
|
+
send("number_with_#{value.is_a?(Integer) ? 'delimiter' : 'precision'}", value, options[:i18n_options] || {})
|
193
|
+
else
|
194
|
+
value
|
195
|
+
end
|
179
196
|
end
|
180
197
|
clean_column_value(value)
|
181
198
|
end
|
@@ -196,18 +213,26 @@ module ActiveScaffold
|
|
196
213
|
end
|
197
214
|
end
|
198
215
|
|
216
|
+
def association_join_text(column = nil)
|
217
|
+
column_value = column&.association_join_text
|
218
|
+
return column_value if column_value
|
219
|
+
return @_association_join_text if defined? @_association_join_text
|
220
|
+
@_association_join_text = active_scaffold_config.list.association_join_text
|
221
|
+
end
|
222
|
+
|
199
223
|
def format_collection_association_value(value, column, label_method, size)
|
200
|
-
|
224
|
+
associated_limit = column.associated_limit
|
225
|
+
if associated_limit.nil?
|
201
226
|
firsts = value.collect(&label_method)
|
202
|
-
safe_join firsts,
|
203
|
-
elsif
|
227
|
+
safe_join firsts, association_join_text(column)
|
228
|
+
elsif associated_limit.zero?
|
204
229
|
size if column.associated_number?
|
205
230
|
else
|
206
|
-
firsts = value.loaded? ? value[0,
|
231
|
+
firsts = value.loaded? ? value[0, associated_limit] : value.limit(associated_limit)
|
207
232
|
firsts = firsts.map(&label_method)
|
208
|
-
firsts << '…' if value.size >
|
209
|
-
text = safe_join firsts,
|
210
|
-
text << " (#{size})" if column.associated_number? &&
|
233
|
+
firsts << '…' if value.size > associated_limit
|
234
|
+
text = safe_join firsts, association_join_text(column)
|
235
|
+
text << " (#{size})" if column.associated_number? && associated_limit && value.size > associated_limit
|
211
236
|
text
|
212
237
|
end
|
213
238
|
end
|
@@ -237,7 +262,7 @@ module ActiveScaffold
|
|
237
262
|
empty_field_text
|
238
263
|
elsif column_value.is_a?(Time) || column_value.is_a?(Date)
|
239
264
|
l(column_value, :format => options[:format] || :default)
|
240
|
-
elsif
|
265
|
+
elsif !!column_value == column_value # rubocop:disable Style/DoubleNegation fast check for boolean
|
241
266
|
as_(column_value.to_s.to_sym)
|
242
267
|
else
|
243
268
|
column_value.to_s
|
@@ -246,15 +271,21 @@ module ActiveScaffold
|
|
246
271
|
end
|
247
272
|
|
248
273
|
def cache_association(association, column, size)
|
274
|
+
associated_limit = column.associated_limit
|
249
275
|
# we are not using eager loading, cache firsts records in order not to query the database for whole association in a future
|
250
|
-
if
|
276
|
+
if associated_limit.nil?
|
251
277
|
logger.warn "ActiveScaffold: Enable eager loading for #{column.name} association to reduce SQL queries"
|
252
|
-
elsif
|
278
|
+
elsif associated_limit.positive?
|
253
279
|
# load at least one record more, is needed to display '...'
|
254
|
-
association.target = association.reader.limit(
|
280
|
+
association.target = association.reader.limit(associated_limit + 1).select(column.select_associated_columns || "#{association.klass.quoted_table_name}.*").to_a
|
255
281
|
elsif @cache_associations
|
256
282
|
# set array with at least one element if size > 0, so blank? or present? works, saving [nil] may cause exceptions
|
257
|
-
association.target =
|
283
|
+
association.target =
|
284
|
+
if size.to_i.zero?
|
285
|
+
[]
|
286
|
+
else
|
287
|
+
ActiveScaffold::Registry.cache(:cached_empty_association, association.klass) { [association.klass.new] }
|
288
|
+
end
|
258
289
|
end
|
259
290
|
end
|
260
291
|
|
@@ -265,14 +296,9 @@ module ActiveScaffold
|
|
265
296
|
def inplace_edit?(record, column)
|
266
297
|
return unless column.inplace_edit
|
267
298
|
if controller.respond_to?(:update_authorized?, true)
|
268
|
-
|
269
|
-
return Array(controller.send(:update_authorized?, record, column.name))[0]
|
270
|
-
else
|
271
|
-
ActiveSupport::Deprecation.warn 'add column = nil parameter to update_authorized? on your controller'
|
272
|
-
editable = Array(controller.send(:update_authorized?, record))[0]
|
273
|
-
end
|
299
|
+
return Array(controller.send(:update_authorized?, record, column.name))[0]
|
274
300
|
end
|
275
|
-
|
301
|
+
record.authorized_for?(:crud_type => :update, :column => column.name)
|
276
302
|
end
|
277
303
|
|
278
304
|
def inplace_edit_cloning?(column)
|
@@ -280,23 +306,29 @@ module ActiveScaffold
|
|
280
306
|
end
|
281
307
|
|
282
308
|
def active_scaffold_inplace_edit_tag_options(record, column)
|
283
|
-
|
284
|
-
|
285
|
-
|
309
|
+
@_inplace_edit_title ||= as_(:click_to_edit)
|
310
|
+
cell_id = ActiveScaffold::Registry.cache :inplace_edit_id, column.cache_key do
|
311
|
+
element_cell_id(id: '--ID--', action: 'update_column', name: column.name.to_s)
|
312
|
+
end
|
313
|
+
tag_options = {id: cell_id.sub('--ID--', record.id.to_s), class: 'in_place_editor_field',
|
314
|
+
title: @_inplace_edit_title, data: {:ie_id => record.to_param}}
|
286
315
|
tag_options[:data][:ie_update] = column.inplace_edit if column.inplace_edit != true
|
287
316
|
tag_options
|
288
317
|
end
|
289
318
|
|
290
319
|
def active_scaffold_inplace_edit(record, column, options = {})
|
291
320
|
formatted_column = options[:formatted_column] || format_column_value(record, column)
|
292
|
-
content_tag(:span, as_(:inplace_edit_handle), :class => 'handle')
|
293
|
-
|
321
|
+
@_inplace_edit_handle ||= content_tag(:span, as_(:inplace_edit_handle), :class => 'handle')
|
322
|
+
span = content_tag(:span, formatted_column, active_scaffold_inplace_edit_tag_options(record, column))
|
323
|
+
@_inplace_edit_handle + span
|
294
324
|
end
|
295
325
|
|
296
326
|
def inplace_edit_control(column)
|
297
327
|
return unless inplace_edit?(active_scaffold_config.model, column) && inplace_edit_cloning?(column)
|
298
|
-
|
299
|
-
|
328
|
+
unless ActiveScaffold.threadsafe
|
329
|
+
column = column.dup
|
330
|
+
column.options = column.options.dup
|
331
|
+
end
|
300
332
|
column.form_ui = :select if column.association && column.form_ui.nil?
|
301
333
|
options = active_scaffold_input_options(column).merge(:object => column.active_record_class.new)
|
302
334
|
options[:class] = "#{options[:class]} inplace_field"
|
@@ -309,6 +341,7 @@ module ActiveScaffold
|
|
309
341
|
'as_inplace_pattern'
|
310
342
|
end
|
311
343
|
|
344
|
+
INPLACE_EDIT_PLURAL_FORM_UI = %i[select record_select].freeze
|
312
345
|
def inplace_edit_data(column)
|
313
346
|
data = {}
|
314
347
|
data[:ie_url] = url_for(params_for(:action => 'update_column', :column => column.name, :id => '__id__'))
|
@@ -316,7 +349,7 @@ module ActiveScaffold
|
|
316
349
|
data[:ie_loading_text] = column.options[:loading_text] || as_(:loading)
|
317
350
|
data[:ie_save_text] = column.options[:save_text] || as_(:update)
|
318
351
|
data[:ie_saving_text] = column.options[:saving_text] || as_(:saving)
|
319
|
-
data[:ie_rows] = column.options[:rows] || 5 if column.column
|
352
|
+
data[:ie_rows] = column.options[:rows] || 5 if column.column&.type == :text
|
320
353
|
data[:ie_cols] = column.options[:cols] if column.options[:cols]
|
321
354
|
data[:ie_size] = column.options[:size] if column.options[:size]
|
322
355
|
data[:ie_use_html] = column.options[:use_html] if column.options[:use_html]
|
@@ -327,7 +360,7 @@ module ActiveScaffold
|
|
327
360
|
data[:ie_mode] = :clone
|
328
361
|
elsif column.inplace_edit == :ajax
|
329
362
|
url = url_for(params_for(:controller => params_for[:controller], :action => 'render_field', :id => '__id__', :update_column => column.name))
|
330
|
-
plural = column.association
|
363
|
+
plural = column.association&.collection? && !override_form_field?(column) && INPLACE_EDIT_PLURAL_FORM_UI.include?(column.form_ui)
|
331
364
|
data[:ie_render_url] = url
|
332
365
|
data[:ie_mode] = :ajax
|
333
366
|
data[:ie_plural] = plural
|
@@ -366,8 +399,8 @@ module ActiveScaffold
|
|
366
399
|
:ie_mode => :inline_checkbox,
|
367
400
|
:ie_url => url_for(params_for(:action => 'mark', :id => '__id__'))
|
368
401
|
}
|
369
|
-
|
370
|
-
tag_options[:data] = inplace_edit_data(column)
|
402
|
+
elsif column.inplace_edit
|
403
|
+
tag_options[:data] = inplace_edit_data(column)
|
371
404
|
end
|
372
405
|
content_tag(:th, column_heading_value(column, sorting, sort_direction) + inplace_edit_control(column), tag_options)
|
373
406
|
end
|
@@ -398,16 +431,16 @@ module ActiveScaffold
|
|
398
431
|
|
399
432
|
# CALCULATIONS
|
400
433
|
|
401
|
-
def column_calculation(column)
|
434
|
+
def column_calculation(column, id_condition: true)
|
402
435
|
if column.calculate.instance_of? Proc
|
403
436
|
column.calculate.call(@records)
|
404
437
|
else
|
405
|
-
calculate_query.calculate(column.calculate, column.name)
|
438
|
+
calculate_query(id_condition).calculate(column.calculate, column.name)
|
406
439
|
end
|
407
440
|
end
|
408
441
|
|
409
|
-
def render_column_calculation(column)
|
410
|
-
calculation = column_calculation(column)
|
442
|
+
def render_column_calculation(column, id_condition: true)
|
443
|
+
calculation = column_calculation(column, id_condition: id_condition)
|
411
444
|
override_formatter = "render_#{column.name}_#{column.calculate.is_a?(Proc) ? :calculate : column.calculate}"
|
412
445
|
calculation = send(override_formatter, calculation) if respond_to? override_formatter
|
413
446
|
format_column_calculation(column, calculation)
|
@@ -21,8 +21,8 @@ module ActiveScaffold
|
|
21
21
|
start_number = 1 if start_number <= 0
|
22
22
|
if current_page.pager.infinite?
|
23
23
|
offsets = [20, 100]
|
24
|
-
|
25
|
-
end_number = current_page.pager.last.number
|
24
|
+
elsif end_number > current_page.pager.last.number
|
25
|
+
end_number = current_page.pager.last.number
|
26
26
|
end
|
27
27
|
|
28
28
|
html = []
|
@@ -29,25 +29,22 @@ module ActiveScaffold
|
|
29
29
|
send(method, record, options)
|
30
30
|
|
31
31
|
# fallback: we get to make the decision
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
text_field(:record, column.name, options.merge(column.options))
|
49
|
-
end
|
50
|
-
end
|
32
|
+
elsif column.association || column.virtual?
|
33
|
+
active_scaffold_search_text(column, options)
|
34
|
+
|
35
|
+
elsif (method = override_search(column.column.type))
|
36
|
+
# if we (or someone else) have created a custom render option for the column type, use that
|
37
|
+
send(method, column, options)
|
38
|
+
|
39
|
+
elsif (method = override_input(column.column.type))
|
40
|
+
# if we (or someone else) have created a custom render option for the column type, use that
|
41
|
+
send(method, column, options)
|
42
|
+
|
43
|
+
else # final ultimate fallback: use rails' generic input method
|
44
|
+
# for textual fields we pass different options
|
45
|
+
text_types = %i[text string integer float decimal]
|
46
|
+
options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
|
47
|
+
text_field(:record, column.name, options.merge(column.options))
|
51
48
|
end
|
52
49
|
rescue StandardError => e
|
53
50
|
logger.error "#{e.class.name}: #{e.message} -- on the ActiveScaffold column = :#{column.name} in #{controller.class}"
|
@@ -61,8 +58,10 @@ module ActiveScaffold
|
|
61
58
|
|
62
59
|
def search_attribute(column, record)
|
63
60
|
column_options = active_scaffold_search_options(column).merge(:object => record)
|
64
|
-
|
65
|
-
|
61
|
+
content_tag :dl do
|
62
|
+
content_tag(:dt, label_tag(search_label_for(column, column_options), search_column_label(column, record))) <<
|
63
|
+
content_tag(:dd, active_scaffold_search_for(column, column_options))
|
64
|
+
end
|
66
65
|
end
|
67
66
|
|
68
67
|
def search_label_for(column, options)
|
@@ -135,8 +134,8 @@ module ActiveScaffold
|
|
135
134
|
def active_scaffold_search_boolean(column, options)
|
136
135
|
select_options = []
|
137
136
|
select_options << [as_(:_select_), nil]
|
138
|
-
select_options << [as_(:true), true]
|
139
|
-
select_options << [as_(:false), false]
|
137
|
+
select_options << [as_(:true), true] # rubocop:disable Lint/BooleanSymbol
|
138
|
+
select_options << [as_(:false), false] # rubocop:disable Lint/BooleanSymbol
|
140
139
|
|
141
140
|
select_tag(options[:name], options_for_select(select_options, ActiveScaffold::Core.column_type_cast(options[:value], column.column)), :id => options[:id])
|
142
141
|
end
|
@@ -166,7 +165,7 @@ module ActiveScaffold
|
|
166
165
|
def active_scaffold_search_null(column, options)
|
167
166
|
select_options = []
|
168
167
|
select_options << [as_(:_select_), nil]
|
169
|
-
select_options.concat
|
168
|
+
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
170
169
|
select_tag(options[:name], options_for_select(select_options, options[:value]), :id => options[:id])
|
171
170
|
end
|
172
171
|
|
@@ -187,7 +186,7 @@ module ActiveScaffold
|
|
187
186
|
select_options.unshift(*comparators)
|
188
187
|
end
|
189
188
|
if include_null_comparators? column
|
190
|
-
select_options.concat
|
189
|
+
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
191
190
|
end
|
192
191
|
select_options
|
193
192
|
end
|
@@ -195,9 +194,9 @@ module ActiveScaffold
|
|
195
194
|
def include_null_comparators?(column)
|
196
195
|
return column.options[:null_comparators] if column.options.key? :null_comparators
|
197
196
|
if column.association
|
198
|
-
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].column
|
197
|
+
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].column&.null
|
199
198
|
else
|
200
|
-
column.column
|
199
|
+
column.column&.null
|
201
200
|
end
|
202
201
|
end
|
203
202
|
|
@@ -205,11 +204,7 @@ module ActiveScaffold
|
|
205
204
|
opt_value, from_value, to_value = field_search_params_range_values(column)
|
206
205
|
|
207
206
|
select_options = active_scaffold_search_range_comparator_options(column)
|
208
|
-
|
209
|
-
text_field_size = 15
|
210
|
-
else
|
211
|
-
text_field_size = 10
|
212
|
-
end
|
207
|
+
text_field_size = active_scaffold_search_range_string?(column) ? 15 : 10
|
213
208
|
opt_value ||= select_options[0][1]
|
214
209
|
|
215
210
|
from_value = controller.class.condition_value_for_numeric(column, from_value)
|
@@ -225,7 +220,7 @@ module ActiveScaffold
|
|
225
220
|
content_tag(
|
226
221
|
:span,
|
227
222
|
safe_join([' - ', send(input_method, "#{options[:name]}[to]", to_value, to_options)]),
|
228
|
-
:id => "#{options[:id]}_between", :class => 'as_search_range_between', :style => (opt_value == 'BETWEEN')
|
223
|
+
:id => "#{options[:id]}_between", :class => 'as_search_range_between', :style => ('display: none' unless opt_value == 'BETWEEN')
|
229
224
|
)
|
230
225
|
end
|
231
226
|
content_tag :span, html, :class => 'search_range'
|
@@ -250,16 +245,23 @@ module ActiveScaffold
|
|
250
245
|
options = column.options.merge(options)
|
251
246
|
type = "#{'date' unless options[:discard_date]}#{'time' unless options[:discard_time]}"
|
252
247
|
use_select = options.delete(:use_select)
|
253
|
-
|
248
|
+
from_name = "#{options[:name]}[from]"
|
249
|
+
to_name = "#{options[:name]}[to]"
|
254
250
|
if use_select
|
255
|
-
|
256
|
-
|
251
|
+
helper = "select_#{type}"
|
252
|
+
fields = [
|
253
|
+
send(helper, field_search_datetime_value(from_value), options.reverse_merge(include_blank: true, prefix: from_name)),
|
254
|
+
send(helper, field_search_datetime_value(to_value), options.reverse_merge(include_blank: true, prefix: to_name))
|
255
|
+
]
|
256
|
+
else
|
257
|
+
helper = "#{type}#{'_local' if type == 'datetime'}_field_tag"
|
258
|
+
fields = [
|
259
|
+
send(helper, from_name, field_search_datetime_value(from_value), options.except(:name, :object).merge(id: "#{options[:id]}_from")),
|
260
|
+
send(helper, to_name, field_search_datetime_value(to_value), options.except(:name, :object).merge(id: "#{options[:id]}_to"))
|
261
|
+
]
|
257
262
|
end
|
258
263
|
|
259
|
-
safe_join
|
260
|
-
send(helper, field_search_datetime_value(from_value), options.reverse_merge(default_from_options || {})),
|
261
|
-
send(helper, field_search_datetime_value(to_value), options.reverse_merge(default_to_options || {}))
|
262
|
-
], ' - '
|
264
|
+
safe_join fields, ' - '
|
263
265
|
end
|
264
266
|
|
265
267
|
def active_scaffold_search_date(column, options)
|
@@ -292,7 +294,7 @@ module ActiveScaffold
|
|
292
294
|
def visibles_and_hiddens(search_config)
|
293
295
|
visibles = []
|
294
296
|
hiddens = []
|
295
|
-
search_config.columns.
|
297
|
+
search_config.columns.each_column do |column|
|
296
298
|
next unless column.search_sql
|
297
299
|
if search_config.optional_columns.include?(column.name) && !searched_by?(column)
|
298
300
|
hiddens << column
|