active_scaffold 3.6.20 → 3.7.1
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/CHANGELOG.rdoc +47 -0
- data/README.md +29 -16
- data/app/assets/javascripts/jquery/active_scaffold.js +106 -68
- data/app/assets/javascripts/jquery/active_scaffold_chosen.js +6 -5
- data/app/assets/javascripts/jquery/tiny_mce_bridge.js +18 -4
- data/app/assets/stylesheets/active_scaffold_layout.css +13 -2
- data/app/views/active_scaffold_overrides/_base_form.html.erb +5 -1
- data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -0
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +24 -13
- data/config/locales/de.yml +6 -3
- data/config/locales/en.yml +3 -0
- data/config/locales/es.yml +3 -0
- data/config/locales/fr.yml +9 -6
- data/config/locales/hu.yml +20 -17
- data/config/locales/ja.yml +83 -80
- data/config/locales/ru.yml +17 -14
- data/lib/active_scaffold/actions/common_search.rb +2 -2
- data/lib/active_scaffold/actions/core.rb +30 -10
- data/lib/active_scaffold/actions/field_search.rb +9 -6
- data/lib/active_scaffold/actions/nested.rb +7 -7
- data/lib/active_scaffold/actions/update.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +22 -70
- data/lib/active_scaffold/bridges/active_storage/active_storage_helpers.rb +0 -3
- data/lib/active_scaffold/bridges/active_storage/form_ui.rb +6 -6
- data/lib/active_scaffold/bridges/active_storage/list_ui.rb +7 -7
- data/lib/active_scaffold/bridges/active_storage.rb +3 -0
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +2 -2
- data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +12 -14
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen/helpers.rb +10 -10
- data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +7 -7
- data/lib/active_scaffold/bridges/date_picker/ext.rb +20 -9
- data/lib/active_scaffold/bridges/date_picker/helper.rb +9 -9
- data/lib/active_scaffold/bridges/date_picker.rb +2 -0
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +5 -5
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +3 -3
- data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +1 -1
- data/lib/active_scaffold/bridges/paper_trail/actions.rb +4 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -3
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +17 -17
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
- data/lib/active_scaffold/bridges/tiny_mce.rb +1 -1
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +6 -11
- data/lib/active_scaffold/bridges.rb +0 -3
- data/lib/active_scaffold/config/core.rb +1 -1
- data/lib/active_scaffold/config/field_search.rb +9 -1
- data/lib/active_scaffold/config/form.rb +9 -1
- data/lib/active_scaffold/constraints.rb +22 -7
- data/lib/active_scaffold/core.rb +6 -10
- data/lib/active_scaffold/data_structures/action_columns.rb +0 -25
- data/lib/active_scaffold/data_structures/action_links.rb +1 -1
- data/lib/active_scaffold/data_structures/association/abstract.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_mongoid.rb +8 -0
- data/lib/active_scaffold/data_structures/association/active_record.rb +1 -13
- data/lib/active_scaffold/data_structures/association/mongoid.rb +21 -8
- data/lib/active_scaffold/data_structures/column.rb +139 -28
- data/lib/active_scaffold/data_structures/columns.rb +12 -12
- data/lib/active_scaffold/data_structures/nested_info.rb +12 -0
- data/lib/active_scaffold/data_structures/sorting.rb +1 -1
- data/lib/active_scaffold/engine.rb +15 -1
- data/lib/active_scaffold/extensions/action_view_rendering.rb +13 -5
- data/lib/active_scaffold/extensions/cow_proxy.rb +1 -1
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
- data/lib/active_scaffold/extensions/unsaved_record.rb +9 -3
- data/lib/active_scaffold/finder.rb +147 -28
- data/lib/active_scaffold/helpers/action_link_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
- data/lib/active_scaffold/helpers/form_column_helpers.rb +153 -107
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
- data/lib/active_scaffold/helpers/list_column_helpers.rb +37 -20
- data/lib/active_scaffold/helpers/search_column_helpers.rb +137 -55
- data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/orm_checks.rb +21 -1
- data/lib/active_scaffold/registry.rb +10 -15
- data/lib/active_scaffold/tableless.rb +10 -79
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/active_scaffold.rb +3 -9
- data/lib/generators/active_scaffold/install_generator.rb +2 -2
- data/test/bridges/bridge_test.rb +1 -1
- data/test/bridges/date_picker_test.rb +3 -2
- data/test/bridges/paperclip_test.rb +18 -14
- data/test/bridges/tiny_mce_test.rb +5 -3
- data/test/config/base_test.rb +1 -1
- data/test/config/core_test.rb +1 -1
- data/test/config/create_test.rb +1 -1
- data/test/config/delete_test.rb +1 -1
- data/test/config/field_search_test.rb +1 -1
- data/test/config/list_test.rb +1 -1
- data/test/config/nested_test.rb +1 -1
- data/test/config/search_test.rb +1 -1
- data/test/config/show_test.rb +1 -1
- data/test/config/subform_test.rb +1 -1
- data/test/config/update_test.rb +1 -1
- data/test/data_structures/action_columns_test.rb +1 -1
- data/test/data_structures/action_link_test.rb +1 -1
- data/test/data_structures/action_links_test.rb +1 -1
- data/test/data_structures/actions_test.rb +1 -1
- data/test/data_structures/association_column_test.rb +1 -1
- data/test/data_structures/column_test.rb +1 -1
- data/test/data_structures/columns_test.rb +1 -1
- data/test/data_structures/set_test.rb +1 -1
- data/test/data_structures/sorting_test.rb +1 -1
- data/test/data_structures/standard_column_test.rb +1 -1
- data/test/data_structures/validation_reflection_test.rb +1 -1
- data/test/data_structures/virtual_column_test.rb +1 -1
- data/test/extensions/active_record_test.rb +1 -1
- data/test/helpers/form_column_helpers_test.rb +7 -5
- data/test/helpers/pagination_helpers_test.rb +1 -1
- data/test/helpers/search_column_helpers_test.rb +2 -1
- data/test/misc/active_record_permissions_test.rb +1 -1
- data/test/misc/attribute_params_test.rb +1 -1
- data/test/misc/calculation_test.rb +1 -1
- data/test/misc/configurable_test.rb +1 -1
- data/test/misc/constraints_test.rb +2 -1
- data/test/misc/convert_numbers_format_test.rb +1 -1
- data/test/misc/finder_test.rb +39 -1
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/parse_datetime_test.rb +1 -1
- data/test/misc/tableless_test.rb +1 -1
- data/test/test_helper.rb +4 -4
- metadata +5 -17
- data/config/brakeman.ignore +0 -26
- data/config/brakeman.yml +0 -3
- data/config/i18n-tasks.yml +0 -121
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +0 -221
- data/lib/active_scaffold/delayed_setup.rb +0 -41
- data/lib/active_scaffold/extensions/left_outer_joins.rb +0 -43
|
@@ -5,8 +5,13 @@ module ActiveScaffold
|
|
|
5
5
|
def get_column_value(record, column)
|
|
6
6
|
record = record.send(column.delegated_association.name) if column.delegated_association
|
|
7
7
|
if record
|
|
8
|
-
method = get_column_method(record, column)
|
|
9
|
-
value =
|
|
8
|
+
method, list_ui = get_column_method(record, column)
|
|
9
|
+
value =
|
|
10
|
+
if list_ui
|
|
11
|
+
send(method, record, column, ui_options: column.list_ui_options || column.options)
|
|
12
|
+
else
|
|
13
|
+
send(method, record, column)
|
|
14
|
+
end
|
|
10
15
|
else
|
|
11
16
|
value = nil
|
|
12
17
|
end
|
|
@@ -27,8 +32,8 @@ module ActiveScaffold
|
|
|
27
32
|
method
|
|
28
33
|
# second, check if the dev has specified a valid list_ui for this column
|
|
29
34
|
elsif column.list_ui && (method = override_column_ui(column.list_ui))
|
|
30
|
-
method
|
|
31
|
-
elsif column.column && (method = override_column_ui(column.
|
|
35
|
+
[method, true]
|
|
36
|
+
elsif column.column && (method = override_column_ui(column.column_type))
|
|
32
37
|
method
|
|
33
38
|
else
|
|
34
39
|
:format_column_value
|
|
@@ -76,52 +81,63 @@ module ActiveScaffold
|
|
|
76
81
|
##
|
|
77
82
|
## Overrides
|
|
78
83
|
##
|
|
79
|
-
def active_scaffold_column_text(record, column)
|
|
84
|
+
def active_scaffold_column_text(record, column, ui_options: column.options)
|
|
80
85
|
# `to_s` is necessary to convert objects in serialized columns to string before truncation.
|
|
81
|
-
clean_column_value(truncate(record.send(column.name).to_s, :
|
|
86
|
+
clean_column_value(truncate(record.send(column.name).to_s, length: ui_options[:truncate] || 50))
|
|
82
87
|
end
|
|
83
88
|
|
|
84
|
-
def active_scaffold_column_fulltext(record, column)
|
|
89
|
+
def active_scaffold_column_fulltext(record, column, ui_options: column.options)
|
|
85
90
|
clean_column_value(record.send(column.name))
|
|
86
91
|
end
|
|
87
92
|
|
|
88
|
-
def active_scaffold_column_marked(record, column)
|
|
93
|
+
def active_scaffold_column_marked(record, column, ui_options: column.options)
|
|
89
94
|
options = {:id => nil, :object => record}
|
|
90
95
|
content_tag(:span, check_box(:record, column.name, options), :class => 'in_place_editor_field', :data => {:ie_id => record.to_param})
|
|
91
96
|
end
|
|
92
97
|
|
|
93
|
-
def active_scaffold_column_checkbox(record, column)
|
|
98
|
+
def active_scaffold_column_checkbox(record, column, ui_options: column.options)
|
|
94
99
|
options = {:disabled => true, :id => nil, :object => record}
|
|
95
100
|
options.delete(:disabled) if inplace_edit?(record, column)
|
|
96
101
|
check_box(:record, column.name, options)
|
|
97
102
|
end
|
|
98
103
|
|
|
99
|
-
def
|
|
100
|
-
|
|
104
|
+
def active_scaffold_column_boolean(record, column, ui_options: column.options)
|
|
105
|
+
value = record.send(column.name)
|
|
106
|
+
if value.nil? && ui_options[:include_blank]
|
|
107
|
+
value = ui_options[:include_blank]
|
|
108
|
+
value.is_a?(Symbol) ? as_(value) : value
|
|
109
|
+
else
|
|
110
|
+
format_column_value(record, column, value)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def active_scaffold_column_percentage(record, column, ui_options: column.options)
|
|
115
|
+
options = ui_options[:slider] || {}
|
|
101
116
|
options = options.merge(min: record.send(options[:min_method])) if options[:min_method]
|
|
102
117
|
options = options.merge(max: record.send(options[:max_method])) if options[:max_method]
|
|
103
118
|
value = record.send(options[:value_method]) if options[:value_method]
|
|
104
119
|
as_slider options.merge(value: value || record.send(column.name))
|
|
105
120
|
end
|
|
106
121
|
|
|
107
|
-
def active_scaffold_column_month(record, column)
|
|
122
|
+
def active_scaffold_column_month(record, column, ui_options: column.options)
|
|
108
123
|
l record.send(column.name), format: :year_month
|
|
109
124
|
end
|
|
110
125
|
|
|
111
|
-
def active_scaffold_column_week(record, column)
|
|
126
|
+
def active_scaffold_column_week(record, column, ui_options: column.options)
|
|
112
127
|
l record.send(column.name), format: :week
|
|
113
128
|
end
|
|
114
129
|
|
|
115
130
|
def tel_to(text)
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
text = text.to_s
|
|
132
|
+
groups = text.scan(/(?:^\+)?\d+/)
|
|
133
|
+
extension = groups.pop if text.match?(/\s*[^\d\s]+\s*\d+$/)
|
|
118
134
|
link_to text, "tel:#{[groups.join('-'), extension].compact.join(',')}"
|
|
119
135
|
end
|
|
120
136
|
|
|
121
|
-
def active_scaffold_column_telephone(record, column)
|
|
137
|
+
def active_scaffold_column_telephone(record, column, ui_options: column.options)
|
|
122
138
|
phone = record.send column.name
|
|
123
139
|
return if phone.blank?
|
|
124
|
-
phone = number_to_phone(phone) unless
|
|
140
|
+
phone = number_to_phone(phone) unless ui_options[:format] == false
|
|
125
141
|
tel_to phone
|
|
126
142
|
end
|
|
127
143
|
|
|
@@ -146,8 +162,9 @@ module ActiveScaffold
|
|
|
146
162
|
def format_column_value(record, column, value = nil)
|
|
147
163
|
value ||= record.send(column.name) unless record.nil?
|
|
148
164
|
if column.association.nil?
|
|
149
|
-
if FORM_UI_WITH_OPTIONS.include?(column.form_ui)
|
|
150
|
-
|
|
165
|
+
form_ui_options = column.form_ui_options || column.options if FORM_UI_WITH_OPTIONS.include?(column.form_ui)
|
|
166
|
+
if form_ui_options&.dig(:options)
|
|
167
|
+
text, val = form_ui_options[:options].find { |t, v| (v.nil? ? t : v).to_s == value.to_s }
|
|
151
168
|
value = active_scaffold_translated_option(column, text, val).first if text
|
|
152
169
|
end
|
|
153
170
|
if grouped_search? && column == search_group_column && search_group_function
|
|
@@ -302,7 +319,7 @@ module ActiveScaffold
|
|
|
302
319
|
end
|
|
303
320
|
|
|
304
321
|
def inplace_edit_cloning?(column)
|
|
305
|
-
column.inplace_edit != :ajax && (override_form_field?(column) || column.form_ui || (column.column && override_input?(column.
|
|
322
|
+
column.inplace_edit != :ajax && (override_form_field?(column) || column.form_ui || (column.column && override_input?(column.column_type)))
|
|
306
323
|
end
|
|
307
324
|
|
|
308
325
|
def active_scaffold_inplace_edit_tag_options(record, column)
|
|
@@ -6,6 +6,8 @@ module ActiveScaffold
|
|
|
6
6
|
# It does not do any rendering. It only decides which method is responsible for rendering.
|
|
7
7
|
def active_scaffold_search_for(column, options = nil)
|
|
8
8
|
options ||= active_scaffold_search_options(column)
|
|
9
|
+
search_columns = active_scaffold_config.field_search.columns.visible_columns_names
|
|
10
|
+
options = update_columns_options(column, nil, options, form_columns: search_columns, url_params: {form_action: :field_search})
|
|
9
11
|
record = options[:object]
|
|
10
12
|
if column.delegated_association
|
|
11
13
|
record = record.send(column.delegated_association.name) || column.active_record_class.new
|
|
@@ -18,11 +20,11 @@ module ActiveScaffold
|
|
|
18
20
|
|
|
19
21
|
# second, check if the dev has specified a valid search_ui for this column, using specific ui for searches
|
|
20
22
|
elsif column.search_ui && (method = override_search(column.search_ui))
|
|
21
|
-
send(method, column, options)
|
|
23
|
+
send(method, column, options, ui_options: column.search_ui_options || column.options)
|
|
22
24
|
|
|
23
25
|
# third, check if the dev has specified a valid search_ui for this column, using generic ui for forms
|
|
24
26
|
elsif column.search_ui && (method = override_input(column.search_ui))
|
|
25
|
-
send(method, column, options)
|
|
27
|
+
send(method, column, options, ui_options: column.search_ui_options || column.options)
|
|
26
28
|
|
|
27
29
|
# fourth, check if the dev has created an override for this specific field
|
|
28
30
|
elsif (method = override_form_field(column))
|
|
@@ -32,18 +34,17 @@ module ActiveScaffold
|
|
|
32
34
|
elsif column.association || column.virtual?
|
|
33
35
|
active_scaffold_search_text(column, options)
|
|
34
36
|
|
|
35
|
-
elsif (method = override_search(column.
|
|
37
|
+
elsif (method = override_search(column.column_type))
|
|
36
38
|
# if we (or someone else) have created a custom render option for the column type, use that
|
|
37
39
|
send(method, column, options)
|
|
38
40
|
|
|
39
|
-
elsif (method = override_input(column.
|
|
41
|
+
elsif (method = override_input(column.column_type))
|
|
40
42
|
# if we (or someone else) have created a custom render option for the column type, use that
|
|
41
43
|
send(method, column, options)
|
|
42
44
|
|
|
43
45
|
else # final ultimate fallback: use rails' generic input method
|
|
44
46
|
# for textual fields we pass different options
|
|
45
|
-
|
|
46
|
-
options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
|
|
47
|
+
options = active_scaffold_input_text_options(options) if column.text? || column.number?
|
|
47
48
|
text_field(:record, column.name, options.merge(column.options))
|
|
48
49
|
end
|
|
49
50
|
rescue StandardError => e
|
|
@@ -72,28 +73,28 @@ module ActiveScaffold
|
|
|
72
73
|
## Search input methods
|
|
73
74
|
##
|
|
74
75
|
|
|
75
|
-
def active_scaffold_search_multi_select(column, options)
|
|
76
|
+
def active_scaffold_search_multi_select(column, options, ui_options: column.options)
|
|
76
77
|
record = options.delete(:object)
|
|
77
78
|
associated = options.delete :value
|
|
78
79
|
associated = [associated].compact unless associated.is_a? Array
|
|
79
80
|
|
|
80
81
|
if column.association
|
|
81
82
|
associated.collect!(&:to_i)
|
|
82
|
-
method =
|
|
83
|
+
method = ui_options[:label_method] || :to_label
|
|
83
84
|
select_options = sorted_association_options_find(column.association, nil, record).collect do |r|
|
|
84
85
|
[r.send(method), r.id]
|
|
85
86
|
end
|
|
86
87
|
else
|
|
87
|
-
select_options = column
|
|
88
|
+
select_options = active_scaffold_enum_options(column, record, ui_options: ui_options).collect do |text, value|
|
|
88
89
|
active_scaffold_translated_option(column, text, value)
|
|
89
90
|
end
|
|
90
91
|
end
|
|
91
92
|
return as_(:no_options) if select_options.empty?
|
|
92
93
|
|
|
93
|
-
active_scaffold_checkbox_list(column, select_options, associated, options)
|
|
94
|
+
active_scaffold_checkbox_list(column, select_options, associated, options, ui_options: ui_options)
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
def active_scaffold_search_select(column, html_options, options = {})
|
|
97
|
+
def active_scaffold_search_select(column, html_options, options = {}, ui_options: column.options)
|
|
97
98
|
record = html_options.delete(:object)
|
|
98
99
|
associated = html_options.delete :value
|
|
99
100
|
if column.association
|
|
@@ -102,13 +103,13 @@ module ActiveScaffold
|
|
|
102
103
|
select_options = sorted_association_options_find(column.association, false, record)
|
|
103
104
|
else
|
|
104
105
|
method = column.name
|
|
105
|
-
select_options = active_scaffold_enum_options(column, record).collect do |text, value|
|
|
106
|
+
select_options = active_scaffold_enum_options(column, record, ui_options: ui_options).collect do |text, value|
|
|
106
107
|
active_scaffold_translated_option(column, text, value)
|
|
107
108
|
end
|
|
108
109
|
end
|
|
109
110
|
|
|
110
|
-
options = options.merge(:
|
|
111
|
-
html_options.merge!
|
|
111
|
+
options = options.merge(selected: associated).merge ui_options
|
|
112
|
+
html_options.merge! ui_options[:html_options] || {}
|
|
112
113
|
if html_options[:multiple]
|
|
113
114
|
active_scaffold_select_name_with_multiple html_options
|
|
114
115
|
else
|
|
@@ -119,21 +120,34 @@ module ActiveScaffold
|
|
|
119
120
|
if (optgroup = options.delete(:optgroup))
|
|
120
121
|
select(:record, method, active_scaffold_grouped_options(column, select_options, optgroup), options, html_options)
|
|
121
122
|
elsif column.association
|
|
122
|
-
collection_select(:record, method, select_options, :id,
|
|
123
|
+
collection_select(:record, method, select_options, :id, ui_options[:label_method] || :to_label, options, html_options)
|
|
123
124
|
else
|
|
124
125
|
select(:record, method, select_options, options, html_options)
|
|
125
126
|
end
|
|
126
127
|
end
|
|
127
128
|
|
|
128
|
-
def
|
|
129
|
+
def active_scaffold_search_select_multiple(column, options, ui_options: column.options)
|
|
130
|
+
active_scaffold_search_select(column, options.merge(multiple: true), ui_options: ui_options)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def active_scaffold_search_draggable(column, options, ui_options: column.options)
|
|
134
|
+
active_scaffold_search_multi_select(column, options.merge(draggable_lists: true), ui_options: ui_options)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def active_scaffold_search_text(column, options, ui_options: column.options)
|
|
129
138
|
text_field :record, column.name, active_scaffold_input_text_options(options)
|
|
130
139
|
end
|
|
131
140
|
|
|
132
141
|
# we can't use active_scaffold_input_boolean because we need to have a nil value even when column can't be null
|
|
133
142
|
# to decide whether search for this field or not
|
|
134
|
-
def active_scaffold_search_boolean(column, options)
|
|
143
|
+
def active_scaffold_search_boolean(column, options, ui_options: column.options)
|
|
135
144
|
select_options = []
|
|
136
145
|
select_options << [as_(:_select_), nil]
|
|
146
|
+
if column.null?
|
|
147
|
+
null_label = ui_options[:include_blank] || :null
|
|
148
|
+
null_label = as_(null_label) if null_label.is_a?(Symbol)
|
|
149
|
+
select_options << [null_label, 'null']
|
|
150
|
+
end
|
|
137
151
|
select_options << [as_(:true), true] # rubocop:disable Lint/BooleanSymbol
|
|
138
152
|
select_options << [as_(:false), false] # rubocop:disable Lint/BooleanSymbol
|
|
139
153
|
|
|
@@ -162,7 +176,7 @@ module ActiveScaffold
|
|
|
162
176
|
end
|
|
163
177
|
end
|
|
164
178
|
|
|
165
|
-
def active_scaffold_search_null(column, options)
|
|
179
|
+
def active_scaffold_search_null(column, options, ui_options: column.options)
|
|
166
180
|
select_options = []
|
|
167
181
|
select_options << [as_(:_select_), nil]
|
|
168
182
|
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
|
@@ -179,38 +193,38 @@ module ActiveScaffold
|
|
|
179
193
|
column.text? || column.search_ui == :string
|
|
180
194
|
end
|
|
181
195
|
|
|
182
|
-
def active_scaffold_search_range_comparator_options(column)
|
|
196
|
+
def active_scaffold_search_range_comparator_options(column, ui_options: column.options)
|
|
183
197
|
select_options = ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
|
184
198
|
if active_scaffold_search_range_string?(column)
|
|
185
199
|
comparators = ActiveScaffold::Finder::STRING_COMPARATORS.collect { |title, comp| [as_(title), comp] }
|
|
186
200
|
select_options.unshift(*comparators)
|
|
187
201
|
end
|
|
188
|
-
if include_null_comparators? column
|
|
202
|
+
if include_null_comparators? column, ui_options: ui_options
|
|
189
203
|
select_options.concat(ActiveScaffold::Finder::NULL_COMPARATORS.collect { |comp| [as_(comp), comp] })
|
|
190
204
|
end
|
|
191
205
|
select_options
|
|
192
206
|
end
|
|
193
207
|
|
|
194
|
-
def include_null_comparators?(column)
|
|
195
|
-
return
|
|
208
|
+
def include_null_comparators?(column, ui_options: column.options)
|
|
209
|
+
return ui_options[:null_comparators] if ui_options.key? :null_comparators
|
|
196
210
|
if column.association
|
|
197
|
-
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].
|
|
211
|
+
!column.association.belongs_to? || active_scaffold_config.columns[column.association.foreign_key].null?
|
|
198
212
|
else
|
|
199
|
-
column.
|
|
213
|
+
column.null?
|
|
200
214
|
end
|
|
201
215
|
end
|
|
202
216
|
|
|
203
|
-
def active_scaffold_search_range(column, options, input_method = :text_field_tag, input_options = {})
|
|
217
|
+
def active_scaffold_search_range(column, options, input_method = :text_field_tag, input_options = {}, ui_options: column.options)
|
|
204
218
|
opt_value, from_value, to_value = field_search_params_range_values(column)
|
|
205
219
|
|
|
206
|
-
select_options = active_scaffold_search_range_comparator_options(column)
|
|
220
|
+
select_options = active_scaffold_search_range_comparator_options(column, ui_options: ui_options)
|
|
207
221
|
text_field_size = active_scaffold_search_range_string?(column) ? 15 : 10
|
|
208
222
|
opt_value ||= select_options[0][1]
|
|
209
223
|
|
|
210
224
|
from_value = controller.class.condition_value_for_numeric(column, from_value)
|
|
211
225
|
to_value = controller.class.condition_value_for_numeric(column, to_value)
|
|
212
|
-
from_value = format_number_value(from_value,
|
|
213
|
-
to_value = format_number_value(to_value,
|
|
226
|
+
from_value = format_number_value(from_value, ui_options) if from_value.is_a?(Numeric)
|
|
227
|
+
to_value = format_number_value(to_value, ui_options) if to_value.is_a?(Numeric)
|
|
214
228
|
html = select_tag("#{options[:name]}[opt]", options_for_select(select_options, opt_value),
|
|
215
229
|
:id => "#{options[:id]}_opt", :class => 'as_search_range_option')
|
|
216
230
|
from_options = active_scaffold_input_text_options(input_options.merge(:id => options[:id], :size => text_field_size))
|
|
@@ -227,51 +241,119 @@ module ActiveScaffold
|
|
|
227
241
|
end
|
|
228
242
|
alias active_scaffold_search_string active_scaffold_search_range
|
|
229
243
|
|
|
230
|
-
def active_scaffold_search_integer(column, options)
|
|
231
|
-
active_scaffold_search_range(column, options, :number_field_tag, step: '1')
|
|
244
|
+
def active_scaffold_search_integer(column, options, ui_options: column.options)
|
|
245
|
+
active_scaffold_search_range(column, options, :number_field_tag, {step: '1'}, ui_options: ui_options) # rubocop:disable Style/BracesAroundHashParameters
|
|
232
246
|
end
|
|
233
247
|
|
|
234
|
-
def active_scaffold_search_decimal(column, options)
|
|
235
|
-
active_scaffold_search_range(column, options, :number_field_tag, step: :any)
|
|
248
|
+
def active_scaffold_search_decimal(column, options, ui_options: column.options)
|
|
249
|
+
active_scaffold_search_range(column, options, :number_field_tag, {step: :any}, ui_options: ui_options) # rubocop:disable Style/BracesAroundHashParameters
|
|
236
250
|
end
|
|
237
251
|
alias active_scaffold_search_float active_scaffold_search_decimal
|
|
238
252
|
|
|
253
|
+
def active_scaffold_search_datetime(column, options, ui_options: column.options, field_ui: column.search_ui || :datetime)
|
|
254
|
+
current_search = {'from' => nil, 'to' => nil, 'opt' => 'BETWEEN',
|
|
255
|
+
'number' => 1, 'unit' => 'DAYS', 'range' => nil}
|
|
256
|
+
current_search.merge!(options[:value]) unless options[:value].nil?
|
|
257
|
+
tags = [
|
|
258
|
+
active_scaffold_search_datetime_comparator_tag(column, options, current_search),
|
|
259
|
+
active_scaffold_search_datetime_trend_tag(column, options, current_search),
|
|
260
|
+
active_scaffold_search_datetime_numeric_tag(column, options, current_search, ui_options: ui_options, field_ui: field_ui),
|
|
261
|
+
active_scaffold_search_datetime_range_tag(column, options, current_search)
|
|
262
|
+
]
|
|
263
|
+
safe_join tags, ' '.html_safe # rubocop:disable Rails/OutputSafety
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def active_scaffold_search_timestamp(column, options, ui_options: column.options)
|
|
267
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :datetime)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def active_scaffold_search_time(column, options, ui_options: column.options)
|
|
271
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :time)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def active_scaffold_search_date(column, options, ui_options: column.options)
|
|
275
|
+
active_scaffold_search_datetime(column, options, ui_options: ui_options, field_ui: :date)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def active_scaffold_search_datetime_comparator_options(column)
|
|
279
|
+
select_options = ActiveScaffold::Finder::DATE_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
|
280
|
+
select_options + ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def active_scaffold_search_datetime_comparator_tag(column, options, current_search)
|
|
284
|
+
choices = options_for_select(active_scaffold_search_datetime_comparator_options(column), current_search['opt'])
|
|
285
|
+
select_tag("#{options[:name]}[opt]", choices, id: "#{options[:id]}_opt", class: 'as_search_range_option as_search_date_time_option')
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def active_scaffold_search_datetime_numeric_tag(column, options, current_search, ui_options: column.options, field_ui: column.search_ui)
|
|
289
|
+
helper = "active_scaffold_search_#{field_ui}_field"
|
|
290
|
+
numeric_controls = [
|
|
291
|
+
send(helper, column, options, current_search, 'from', ui_options: ui_options),
|
|
292
|
+
content_tag(:span, id: "#{options[:id]}_between", class: 'as_search_range_between',
|
|
293
|
+
style: ('display: none' unless current_search['opt'] == 'BETWEEN')) do
|
|
294
|
+
safe_join([' - ', send(helper, column, options, current_search, 'to', ui_options: ui_options)])
|
|
295
|
+
end
|
|
296
|
+
]
|
|
297
|
+
content_tag('span', safe_join(numeric_controls),
|
|
298
|
+
:id => "#{options[:id]}_numeric", :class => 'search-date-numeric',
|
|
299
|
+
:style => ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(current_search['opt']) ? nil : 'display: none')
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def active_scaffold_search_datetime_trend_tag(column, options, current_search)
|
|
303
|
+
trend_controls = [
|
|
304
|
+
text_field_tag("#{options[:name]}[number]", current_search['number'], class: 'text-input', size: 10, autocomplete: 'off'),
|
|
305
|
+
select_tag("#{options[:name]}[unit]",
|
|
306
|
+
options_for_select(active_scaffold_search_datetime_trend_units(column), current_search['unit']),
|
|
307
|
+
class: 'text-input')
|
|
308
|
+
]
|
|
309
|
+
content_tag('span', safe_join(trend_controls, ' '),
|
|
310
|
+
id: "#{options[:id]}_trend", class: 'search-date-trend',
|
|
311
|
+
style: ('display: none' unless current_search['opt'] == 'PAST' || current_search['opt'] == 'FUTURE'))
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
def active_scaffold_search_datetime_trend_units(column)
|
|
315
|
+
options = ActiveScaffold::Finder::DATE_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] }
|
|
316
|
+
options = ActiveScaffold::Finder::TIME_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] } + options if column_datetime?(column)
|
|
317
|
+
options
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def active_scaffold_search_datetime_range_tag(column, options, current_search)
|
|
321
|
+
values = ActiveScaffold::Finder::DATE_RANGES.collect { |range| [as_(range.downcase.to_sym), range] }
|
|
322
|
+
range_controls = select_tag("#{options[:name]}[range]",
|
|
323
|
+
options_for_select(values, current_search['range']),
|
|
324
|
+
class: 'text-input', id: nil)
|
|
325
|
+
content_tag('span', range_controls,
|
|
326
|
+
id: "#{options[:id]}_range", class: 'search-date-range',
|
|
327
|
+
style: ('display: none' unless current_search['opt'] == 'RANGE'))
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
def column_datetime?(column)
|
|
331
|
+
(!column.column.nil? && %i[datetime time].include?(column.column_type))
|
|
332
|
+
end
|
|
333
|
+
|
|
239
334
|
def field_search_datetime_value(value)
|
|
240
335
|
Time.zone.local(value[:year].to_i, value[:month].to_i, value[:day].to_i, value[:hour].to_i, value[:minute].to_i, value[:second].to_i) unless value.nil? || value[:year].blank?
|
|
241
336
|
end
|
|
242
337
|
|
|
243
|
-
def
|
|
244
|
-
|
|
245
|
-
options = column.options.merge(options)
|
|
338
|
+
def active_scaffold_search_datetime_field(column, options, current_search, name, ui_options: column.options)
|
|
339
|
+
options = ui_options.merge(options)
|
|
246
340
|
type = "#{'date' unless options[:discard_date]}#{'time' unless options[:discard_time]}"
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if use_select
|
|
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
|
-
]
|
|
341
|
+
field_name = "#{options[:name]}[#{name}]"
|
|
342
|
+
if options[:use_select]
|
|
343
|
+
send("select_#{type}", current_search[name], options.reverse_merge(include_blank: true, prefix: field_name))
|
|
256
344
|
else
|
|
257
345
|
helper = "#{type}#{'_local' if type == 'datetime'}_field_tag"
|
|
258
|
-
|
|
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
|
-
]
|
|
346
|
+
send(helper, field_name, current_search[name], options.except(:name, :object, :use_select).merge(id: "#{options[:id]}_#{name}"))
|
|
262
347
|
end
|
|
263
|
-
|
|
264
|
-
safe_join fields, ' - '
|
|
265
348
|
end
|
|
266
349
|
|
|
267
|
-
def
|
|
268
|
-
|
|
350
|
+
def active_scaffold_search_date_field(column, options, current_search, name, ui_options: column.options)
|
|
351
|
+
active_scaffold_search_datetime_field(column, options.merge!(:discard_time => true), current_search, name, ui_options: ui_options)
|
|
269
352
|
end
|
|
270
353
|
|
|
271
|
-
def
|
|
272
|
-
|
|
354
|
+
def active_scaffold_search_time_field(column, options, current_search, name, ui_options: column.options)
|
|
355
|
+
active_scaffold_search_datetime_field(column, options.merge!(:discard_date => true), current_search, name, ui_options: ui_options)
|
|
273
356
|
end
|
|
274
|
-
alias active_scaffold_search_timestamp active_scaffold_search_datetime
|
|
275
357
|
|
|
276
358
|
##
|
|
277
359
|
## Search column override signatures
|
|
@@ -13,24 +13,24 @@ module ActiveScaffold
|
|
|
13
13
|
send(method, value_record, column)
|
|
14
14
|
# second, check if the dev has specified a valid list_ui for this column
|
|
15
15
|
elsif column.show_ui && (method = override_show_column_ui(column.show_ui))
|
|
16
|
-
send(method, value_record, column)
|
|
17
|
-
elsif column.column && (method = override_show_column_ui(column.
|
|
16
|
+
send(method, value_record, column, ui_options: column.show_ui_options || column.options)
|
|
17
|
+
elsif column.column && (method = override_show_column_ui(column.column_type))
|
|
18
18
|
send(method, value_record, column)
|
|
19
19
|
else
|
|
20
20
|
get_column_value(record, column)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
def active_scaffold_show_text(record, column)
|
|
25
|
-
simple_format(clean_column_value(record.send(column.name)))
|
|
24
|
+
def active_scaffold_show_text(record, column, ui_options: column.options)
|
|
25
|
+
simple_format(clean_column_value(record.send(column.name)), ui_options[:html_options], ui_options)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def active_scaffold_show_horizontal(record, column)
|
|
28
|
+
def active_scaffold_show_horizontal(record, column, ui_options: column.options)
|
|
29
29
|
raise ':horizontal show_ui must be used on association column' unless column.association
|
|
30
30
|
render :partial => 'show_association', :locals => {:column => column, :parent_record => record, :show_partial => :horizontal}
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def active_scaffold_show_vertical(record, column)
|
|
33
|
+
def active_scaffold_show_vertical(record, column, ui_options: column.options)
|
|
34
34
|
raise ':vertical show_ui must be used on association column' unless column.association
|
|
35
35
|
render :partial => 'show_association', :locals => {:column => column, :parent_record => record, :show_partial => :vertical}
|
|
36
36
|
end
|
|
@@ -247,7 +247,7 @@ module ActiveScaffold
|
|
|
247
247
|
|
|
248
248
|
message = options.include?(:message) ? options[:message] : as_('errors.template.body')
|
|
249
249
|
|
|
250
|
-
error_messages = objects.sum do |object|
|
|
250
|
+
error_messages = objects.sum([]) do |object|
|
|
251
251
|
object.errors.full_messages.map do |msg|
|
|
252
252
|
options[:list_type] != :br ? content_tag(:li, msg) : msg
|
|
253
253
|
end
|
|
@@ -82,6 +82,22 @@ module ActiveScaffold
|
|
|
82
82
|
type_for_attribute(klass, column_name)
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
|
+
|
|
86
|
+
def default_value(klass, column_name)
|
|
87
|
+
if ActiveScaffold::OrmChecks.mongoid? klass
|
|
88
|
+
columns_hash(klass)[column_name]&.default_val
|
|
89
|
+
elsif ActiveScaffold::OrmChecks.active_record? klass
|
|
90
|
+
klass._default_attributes[column_name]&.value
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def cast(klass, column_name, value)
|
|
95
|
+
if active_record? klass
|
|
96
|
+
type_for_attribute(klass, column_name).cast value
|
|
97
|
+
elsif mongoid? klass
|
|
98
|
+
type_for_attribute(klass, column_name)&.evolve value
|
|
99
|
+
end
|
|
100
|
+
end
|
|
85
101
|
end
|
|
86
102
|
|
|
87
103
|
%i[active_record? mongoid? tableless?].each do |method|
|
|
@@ -96,10 +112,14 @@ module ActiveScaffold
|
|
|
96
112
|
end
|
|
97
113
|
end
|
|
98
114
|
|
|
99
|
-
%i[type_for_attribute column_type].each do |method|
|
|
115
|
+
%i[type_for_attribute column_type default_value].each do |method|
|
|
100
116
|
define_method method do |column_name|
|
|
101
117
|
ActiveScaffold::OrmChecks.send method, active_record_class, column_name
|
|
102
118
|
end
|
|
103
119
|
end
|
|
120
|
+
|
|
121
|
+
def cast(column_name, value)
|
|
122
|
+
ActiveScaffold::OrmChecks.cast active_record_class, column_name, value
|
|
123
|
+
end
|
|
104
124
|
end
|
|
105
125
|
end
|
|
@@ -1,33 +1,28 @@
|
|
|
1
1
|
module ActiveScaffold
|
|
2
2
|
class Registry
|
|
3
|
-
|
|
4
|
-
attr_accessor :current_user_proc, :current_ability_proc, :marked_records
|
|
3
|
+
thread_mattr_accessor :current_user_proc, :current_ability_proc, :marked_records
|
|
5
4
|
|
|
6
|
-
def user_settings
|
|
7
|
-
|
|
5
|
+
def self.user_settings
|
|
6
|
+
RequestStore.store[:attr_Registry_user_settings] ||= {}
|
|
8
7
|
end
|
|
9
8
|
|
|
10
|
-
def constraint_columns
|
|
11
|
-
|
|
9
|
+
def self.constraint_columns
|
|
10
|
+
RequestStore.store[:attr_Registry_constraint_columns] ||= Hash.new { |h, k| h[k] = [] }
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
def unauthorized_columns
|
|
15
|
-
|
|
13
|
+
def self.unauthorized_columns
|
|
14
|
+
RequestStore.store[:attr_Registry_unauthorized_columns] ||= Hash.new { |h, k| h[k] = [] }
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
def cache(kind, key = nil, &block)
|
|
17
|
+
def self.cache(kind, key = nil, &block)
|
|
19
18
|
unless key
|
|
20
19
|
key = kind
|
|
21
20
|
kind = :cache
|
|
22
21
|
end
|
|
23
|
-
|
|
24
|
-
cache =
|
|
22
|
+
RequestStore.store[:attr_Registry_cache] ||= {}
|
|
23
|
+
cache = RequestStore.store[:attr_Registry_cache][kind] ||= {}
|
|
25
24
|
return cache[key] if cache.include? key
|
|
26
25
|
cache[key] ||= yield
|
|
27
26
|
end
|
|
28
|
-
|
|
29
|
-
def self.instance
|
|
30
|
-
RequestStore.store[@per_thread_registry_key] ||= new
|
|
31
|
-
end
|
|
32
27
|
end
|
|
33
28
|
end
|