active_scaffold 3.7.0 → 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 +20 -0
- data/README.md +2 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +68 -62
- data/app/assets/stylesheets/active_scaffold_layout.css +1 -1
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
- data/app/views/active_scaffold_overrides/_render_field.js.erb +9 -6
- 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 +25 -22
- data/config/locales/ru.yml +17 -14
- data/lib/active_scaffold/actions/update.rb +3 -3
- data/lib/active_scaffold/attribute_params.rb +7 -17
- 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/ancestry/ancestry_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 +5 -5
- 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/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 +15 -15
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
- data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +5 -5
- data/lib/active_scaffold/bridges.rb +0 -3
- data/lib/active_scaffold/constraints.rb +22 -7
- data/lib/active_scaffold/core.rb +5 -3
- data/lib/active_scaffold/data_structures/column.rb +108 -23
- data/lib/active_scaffold/engine.rb +15 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
- data/lib/active_scaffold/finder.rb +142 -27
- data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
- data/lib/active_scaffold/helpers/form_column_helpers.rb +114 -94
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
- data/lib/active_scaffold/helpers/list_column_helpers.rb +34 -18
- data/lib/active_scaffold/helpers/search_column_helpers.rb +131 -55
- data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
- data/lib/active_scaffold/orm_checks.rb +21 -1
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold.rb +3 -2
- data/test/bridges/date_picker_test.rb +3 -2
- data/test/bridges/paperclip_test.rb +3 -2
- data/test/bridges/tiny_mce_test.rb +4 -2
- data/test/helpers/form_column_helpers_test.rb +7 -5
- data/test/helpers/search_column_helpers_test.rb +2 -1
- data/test/misc/constraints_test.rb +1 -0
- data/test/misc/finder_test.rb +38 -0
- metadata +2 -6
- 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
@@ -9,6 +9,7 @@ class SearchColumnHelpersTest < ActionView::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_choices_for_boolean_search_ui
|
12
|
-
|
12
|
+
opts = {object: @record, name: 'search[adult]', value: '0'}
|
13
|
+
assert_dom_equal "<select name=\"search[adult]\"><option value=\"\">- select -</option>\n<option value=\"true\">True</option>\n<option value=\"false\" selected=\"selected\">False</option></select>", active_scaffold_search_boolean(@column, opts)
|
13
14
|
end
|
14
15
|
end
|
data/test/misc/finder_test.rb
CHANGED
@@ -78,6 +78,44 @@ class FinderTest < Minitest::Test
|
|
78
78
|
assert_equal ['"people"."adult" = ?', false], ClassWithFinder.condition_for_column(column, '0')
|
79
79
|
end
|
80
80
|
|
81
|
+
def test_condition_for_polymorphic_column
|
82
|
+
column = ActiveScaffold::DataStructures::Column.new('addressable', Address)
|
83
|
+
column.search_sql = [{subquery: [Building, 'name']}]
|
84
|
+
condition = ClassWithFinder.condition_for_column(column, 'test search')
|
85
|
+
assert_equal Building.where(['name LIKE ?', '%test search%']).select(:id).to_sql, condition[1].to_sql
|
86
|
+
assert_equal '"addresses"."addressable_id" IN (?) AND "addresses"."addressable_type" = ?', condition[0]
|
87
|
+
assert_equal ['Building'], condition[2..-1]
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_condition_for_polymorphic_column_with_relation
|
91
|
+
column = ActiveScaffold::DataStructures::Column.new('contactable', Contact)
|
92
|
+
column.search_sql = [{subquery: [Person.joins(:buildings), 'first_name', 'last_name']}]
|
93
|
+
condition = ClassWithFinder.condition_for_column(column, 'test search')
|
94
|
+
assert_equal Person.joins(:buildings).where(['first_name LIKE ? OR last_name LIKE ?', '%test search%', '%test search%']).select(:id).to_sql, condition[1].to_sql
|
95
|
+
assert_equal '"contacts"."contactable_id" IN (?) AND "contacts"."contactable_type" = ?', condition[0]
|
96
|
+
assert_equal ['Person'], condition[2..-1]
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_subquery_condition_for_association_with_condition
|
100
|
+
column = ActiveScaffold::DataStructures::Column.new('owner', Building)
|
101
|
+
column.search_sql = [{subquery: [Person, 'first_name', 'last_name'], conditions: ['floor_count > 0']}]
|
102
|
+
column.search_ui = :text
|
103
|
+
condition = ClassWithFinder.condition_for_column(column, 'test search')
|
104
|
+
assert_equal Person.where(['first_name LIKE ? OR last_name LIKE ?', '%test search%', '%test search%']).select(:id).to_sql, condition[1].to_sql
|
105
|
+
assert_equal '"buildings"."owner_id" IN (?) AND floor_count > 0', condition[0]
|
106
|
+
assert_equal [], condition[2..-1]
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_subquery_condition_for_association_with_conditions
|
110
|
+
column = ActiveScaffold::DataStructures::Column.new('owner', Building)
|
111
|
+
column.search_sql = [{subquery: [Person, 'first_name', 'last_name'], conditions: ['floor_count > 0 AND name != ?', '']}]
|
112
|
+
column.search_ui = :text
|
113
|
+
condition = ClassWithFinder.condition_for_column(column, 'test search')
|
114
|
+
assert_equal Person.where(['first_name LIKE ? OR last_name LIKE ?', '%test search%', '%test search%']).select(:id).to_sql, condition[1].to_sql
|
115
|
+
assert_equal '"buildings"."owner_id" IN (?) AND floor_count > 0 AND name != ?', condition[0]
|
116
|
+
assert_equal [''], condition[2..-1]
|
117
|
+
end
|
118
|
+
|
81
119
|
private
|
82
120
|
|
83
121
|
def relation_class
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.7.
|
4
|
+
version: 3.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Many, see README
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -189,9 +189,6 @@ files:
|
|
189
189
|
- app/views/active_scaffold_overrides/update.html.erb
|
190
190
|
- app/views/active_scaffold_overrides/update_column.js.erb
|
191
191
|
- app/views/active_scaffold_overrides/update_row.js.erb
|
192
|
-
- config/brakeman.ignore
|
193
|
-
- config/brakeman.yml
|
194
|
-
- config/i18n-tasks.yml
|
195
192
|
- config/locales/de.yml
|
196
193
|
- config/locales/en.yml
|
197
194
|
- config/locales/es.yml
|
@@ -267,7 +264,6 @@ files:
|
|
267
264
|
- lib/active_scaffold/bridges/record_select/helpers.rb
|
268
265
|
- lib/active_scaffold/bridges/semantic_attributes.rb
|
269
266
|
- lib/active_scaffold/bridges/semantic_attributes/column.rb
|
270
|
-
- lib/active_scaffold/bridges/shared/date_bridge.rb
|
271
267
|
- lib/active_scaffold/bridges/tiny_mce.rb
|
272
268
|
- lib/active_scaffold/bridges/tiny_mce/helpers.rb
|
273
269
|
- lib/active_scaffold/bridges/usa_state_select.rb
|
data/config/brakeman.ignore
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"ignored_warnings": [
|
3
|
-
{
|
4
|
-
"warning_type": "Weak Hash",
|
5
|
-
"warning_code": 90,
|
6
|
-
"fingerprint": "bca53a490b010fea618ad3791c37086988592b4706fc569f244bca2a3a471bef",
|
7
|
-
"check_name": "WeakHash",
|
8
|
-
"message": "Weak hashing algorithm (MD5) used",
|
9
|
-
"file": "lib/active_scaffold/extensions/action_view_rendering.rb",
|
10
|
-
"line": 99,
|
11
|
-
"link": "http://brakemanscanner.org/docs/warning_types/weak_hash/",
|
12
|
-
"code": "Digest::MD5.hexdigest((params[:controller] + options.to_s))",
|
13
|
-
"render_path": null,
|
14
|
-
"location": {
|
15
|
-
"type": "method",
|
16
|
-
"class": "ActiveScaffold::RenderingHelper",
|
17
|
-
"method": "render_embedded"
|
18
|
-
},
|
19
|
-
"user_input": "params",
|
20
|
-
"confidence": "High",
|
21
|
-
"note": "Hash used for uniquely identify different embedded scaffolds with fixed length id"
|
22
|
-
}
|
23
|
-
],
|
24
|
-
"updated": "2017-10-18 08:35:45 +0200",
|
25
|
-
"brakeman_version": "4.0.1"
|
26
|
-
}
|
data/config/brakeman.yml
DELETED
data/config/i18n-tasks.yml
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
|
2
|
-
|
3
|
-
# The "main" locale.
|
4
|
-
base_locale: en
|
5
|
-
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
|
6
|
-
#locales: [en]
|
7
|
-
## Reporting locale, default: en. Available: en, ru.
|
8
|
-
# internal_locale: en
|
9
|
-
|
10
|
-
# Read and write translations.
|
11
|
-
data:
|
12
|
-
## Translations are read from the file system. Supported format: YAML, JSON.
|
13
|
-
## Provide a custom adapter:
|
14
|
-
# adapter: I18n::Tasks::Data::FileSystem
|
15
|
-
|
16
|
-
# Locale files or `File.find` patterns where translations are read from:
|
17
|
-
read:
|
18
|
-
## Default:
|
19
|
-
- config/locales/%{locale}.yml
|
20
|
-
## More files:
|
21
|
-
# - config/locales/**/*.%{locale}.yml
|
22
|
-
## Another gem (replace %#= with %=):
|
23
|
-
# - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
|
24
|
-
|
25
|
-
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
|
26
|
-
# `i18n-tasks normalize -p` will force move the keys according to these rules
|
27
|
-
write:
|
28
|
-
## For example, write devise and simple form keys to their respective files:
|
29
|
-
# - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
|
30
|
-
## Catch-all default:
|
31
|
-
# - config/locales/%{locale}.yml
|
32
|
-
|
33
|
-
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
|
34
|
-
# router: convervative_router
|
35
|
-
|
36
|
-
yaml:
|
37
|
-
write:
|
38
|
-
# do not wrap lines at 80 characters
|
39
|
-
line_width: -1
|
40
|
-
|
41
|
-
## Pretty-print JSON:
|
42
|
-
# json:
|
43
|
-
# write:
|
44
|
-
# indent: ' '
|
45
|
-
# space: ' '
|
46
|
-
# object_nl: "\n"
|
47
|
-
# array_nl: "\n"
|
48
|
-
|
49
|
-
# Find translate calls
|
50
|
-
search:
|
51
|
-
## Paths or `File.find` patterns to search in:
|
52
|
-
paths:
|
53
|
-
- app/
|
54
|
-
- lib/
|
55
|
-
|
56
|
-
## Root directories for relative keys resolution.
|
57
|
-
# relative_roots:
|
58
|
-
# - app/controllers
|
59
|
-
# - app/helpers
|
60
|
-
# - app/mailers
|
61
|
-
# - app/presenters
|
62
|
-
# - app/views
|
63
|
-
|
64
|
-
## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
|
65
|
-
## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
|
66
|
-
exclude:
|
67
|
-
- app/assets/images
|
68
|
-
- lib/generators/templates
|
69
|
-
|
70
|
-
## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
|
71
|
-
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
|
72
|
-
# only: ["*.rb", "*.html.slim"]
|
73
|
-
|
74
|
-
## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
|
75
|
-
# strict: true
|
76
|
-
|
77
|
-
## Multiple scanners can be used. Their results are merged.
|
78
|
-
## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
|
79
|
-
## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
|
80
|
-
|
81
|
-
## Google Translate
|
82
|
-
# translation:
|
83
|
-
# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
|
84
|
-
# api_key: "AbC-dEf5"
|
85
|
-
|
86
|
-
## Do not consider these keys missing:
|
87
|
-
ignore_missing:
|
88
|
-
# translations from rails i18n are used
|
89
|
-
- date.formats.default
|
90
|
-
- number.currency.format
|
91
|
-
- number.format
|
92
|
-
- number.human.format
|
93
|
-
- number.percentage.format
|
94
|
-
|
95
|
-
## Consider these keys used:
|
96
|
-
ignore_unused:
|
97
|
-
- 'active_scaffold.*' # used indirectly by the ActiveScaffold
|
98
|
-
|
99
|
-
## Exclude these keys from the `i18n-tasks eq-base' report:
|
100
|
-
# ignore_eq_base:
|
101
|
-
# all:
|
102
|
-
# - common.ok
|
103
|
-
# fr,es:
|
104
|
-
# - common.brand
|
105
|
-
|
106
|
-
## Ignore these keys completely:
|
107
|
-
# ignore:
|
108
|
-
# - kaminari.*
|
109
|
-
|
110
|
-
## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
|
111
|
-
## e.g. in case of a relative key defined in a helper method.
|
112
|
-
## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.:
|
113
|
-
#
|
114
|
-
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
|
115
|
-
# only: %w(*.html.haml *.html.slim),
|
116
|
-
# patterns: [['= title\b', '.page_title']] %>
|
117
|
-
#
|
118
|
-
# The PatternMapper can also match key literals via a special %{key} interpolation, e.g.:
|
119
|
-
#
|
120
|
-
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
|
121
|
-
# patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %>
|
@@ -1,221 +0,0 @@
|
|
1
|
-
module ActiveScaffold
|
2
|
-
module Bridges
|
3
|
-
module Shared
|
4
|
-
module DateBridge
|
5
|
-
module SearchColumnHelpers
|
6
|
-
def active_scaffold_search_date_bridge(column, options)
|
7
|
-
current_search = {'from' => nil, 'to' => nil, 'opt' => 'BETWEEN',
|
8
|
-
'number' => 1, 'unit' => 'DAYS', 'range' => nil}
|
9
|
-
current_search.merge!(options[:value]) unless options[:value].nil?
|
10
|
-
tags = []
|
11
|
-
tags << active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
|
12
|
-
tags << active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
|
13
|
-
tags << active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
|
14
|
-
tags << active_scaffold_search_date_bridge_range_tag(column, options, current_search)
|
15
|
-
safe_join tags, ' '.html_safe # rubocop:disable Rails/OutputSafety
|
16
|
-
end
|
17
|
-
|
18
|
-
def active_scaffold_search_date_bridge_comparator_options(column)
|
19
|
-
select_options = ActiveScaffold::Finder::DATE_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
20
|
-
select_options + ActiveScaffold::Finder::NUMERIC_COMPARATORS.collect { |comp| [as_(comp.downcase.to_sym), comp] }
|
21
|
-
end
|
22
|
-
|
23
|
-
def active_scaffold_search_date_bridge_comparator_tag(column, options, current_search)
|
24
|
-
choices = options_for_select(active_scaffold_search_date_bridge_comparator_options(column), current_search['opt'])
|
25
|
-
select_tag("#{options[:name]}[opt]", choices, :id => "#{options[:id]}_opt", :class => 'as_search_range_option as_search_date_time_option')
|
26
|
-
end
|
27
|
-
|
28
|
-
def active_scaffold_search_date_bridge_numeric_tag(column, options, current_search)
|
29
|
-
numeric_controls = [
|
30
|
-
active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'from'),
|
31
|
-
content_tag(:span, safe_join([' - ', active_scaffold_search_date_bridge_calendar_control(column, options, current_search, 'to')]),
|
32
|
-
:id => "#{options[:id]}_between", :class => 'as_search_range_between',
|
33
|
-
:style => current_search['opt'] == 'BETWEEN' ? nil : 'display: none')
|
34
|
-
]
|
35
|
-
content_tag('span', safe_join(numeric_controls),
|
36
|
-
:id => "#{options[:id]}_numeric", :class => 'search-date-numeric',
|
37
|
-
:style => ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(current_search['opt']) ? nil : 'display: none')
|
38
|
-
end
|
39
|
-
|
40
|
-
def active_scaffold_search_date_bridge_trend_tag(column, options, current_search)
|
41
|
-
active_scaffold_date_bridge_trend_tag(column, options,
|
42
|
-
:number_value => current_search['number'],
|
43
|
-
:unit_value => current_search['unit'],
|
44
|
-
:show => (current_search['opt'] == 'PAST' || current_search['opt'] == 'FUTURE'))
|
45
|
-
end
|
46
|
-
|
47
|
-
def active_scaffold_date_bridge_trend_tag(column, options, trend_options)
|
48
|
-
trend_controls = [
|
49
|
-
text_field_tag("#{options[:name]}[number]", trend_options[:number_value], :class => 'text-input', :size => 10, :autocomplete => 'off'),
|
50
|
-
select_tag("#{options[:name]}[unit]",
|
51
|
-
options_for_select(active_scaffold_search_date_bridge_trend_units(column), trend_options[:unit_value]),
|
52
|
-
:class => 'text-input')
|
53
|
-
]
|
54
|
-
content_tag('span', safe_join(trend_controls, ' '),
|
55
|
-
:id => "#{options[:id]}_trend", :class => 'search-date-trend',
|
56
|
-
:style => trend_options[:show] ? nil : 'display: none')
|
57
|
-
end
|
58
|
-
|
59
|
-
def active_scaffold_search_date_bridge_trend_units(column)
|
60
|
-
options = ActiveScaffold::Finder::DATE_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] }
|
61
|
-
options = ActiveScaffold::Finder::TIME_UNITS.collect { |unit| [as_(unit.downcase.to_sym), unit] } + options if column_datetime?(column)
|
62
|
-
options
|
63
|
-
end
|
64
|
-
|
65
|
-
def active_scaffold_search_date_bridge_range_tag(column, options, current_search)
|
66
|
-
values = ActiveScaffold::Finder::DATE_RANGES.collect { |range| [as_(range.downcase.to_sym), range] }
|
67
|
-
range_controls = select_tag("#{options[:name]}[range]",
|
68
|
-
options_for_select(values, current_search['range']),
|
69
|
-
:class => 'text-input', :id => nil)
|
70
|
-
content_tag('span', range_controls,
|
71
|
-
:id => "#{options[:id]}_range", :class => 'search-date-range',
|
72
|
-
:style => ('display: none' unless current_search['opt'] == 'RANGE'))
|
73
|
-
end
|
74
|
-
|
75
|
-
def column_datetime?(column)
|
76
|
-
(!column.column.nil? && %i[datetime time].include?(column.column.type))
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
module HumanConditionHelpers
|
81
|
-
def active_scaffold_human_condition_date_bridge(column, value)
|
82
|
-
case value['opt']
|
83
|
-
when 'RANGE'
|
84
|
-
range_type, range = value['range'].downcase.split('_')
|
85
|
-
format = active_scaffold_human_condition_date_bridge_range_format(range_type, range)
|
86
|
-
from, = controller.class.date_bridge_from_to(column, value)
|
87
|
-
"#{column.active_record_class.human_attribute_name(column.name)} = #{as_(value['range'].downcase).downcase} (#{I18n.l(from, :format => format)})"
|
88
|
-
when 'PAST', 'FUTURE'
|
89
|
-
from, to = controller.class.date_bridge_from_to(column, value)
|
90
|
-
"#{column.active_record_class.human_attribute_name(column.name)} #{as_('BETWEEN'.downcase).downcase} #{I18n.l(from)} - #{I18n.l(to)}"
|
91
|
-
else
|
92
|
-
from, to = controller.class.date_bridge_from_to(column, value)
|
93
|
-
"#{column.active_record_class.human_attribute_name(column.name)} #{as_(value['opt'].downcase).downcase} #{I18n.l(from)} #{value['opt'] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def active_scaffold_human_condition_date_bridge_range_format(range_type, range)
|
98
|
-
case range
|
99
|
-
when 'week'
|
100
|
-
first_day_of_week = I18n.translate 'active_scaffold.date_picker_options.firstDay'
|
101
|
-
if first_day_of_week == 1
|
102
|
-
'%W %Y'
|
103
|
-
else
|
104
|
-
'%U %Y'
|
105
|
-
end
|
106
|
-
when 'month'
|
107
|
-
'%b %Y'
|
108
|
-
when 'year'
|
109
|
-
'%Y'
|
110
|
-
else
|
111
|
-
I18n.translate 'date.formats.default'
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
module Finder
|
117
|
-
module ClassMethods
|
118
|
-
def condition_for_date_bridge_type(column, value, like_pattern)
|
119
|
-
operator = ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(value['opt']) && value['opt'] != 'BETWEEN' ? value['opt'] : nil
|
120
|
-
from_value, to_value = date_bridge_from_to(column, value)
|
121
|
-
|
122
|
-
if column.search_sql.is_a? Proc
|
123
|
-
column.search_sql.call(from_value, to_value, operator)
|
124
|
-
elsif operator.nil?
|
125
|
-
['%<search_sql>s BETWEEN ? AND ?', from_value, to_value] unless from_value.nil? || to_value.nil?
|
126
|
-
else
|
127
|
-
["%<search_sql>s #{value['opt']} ?", from_value] unless from_value.nil?
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def date_bridge_from_to(column, value)
|
132
|
-
conversion = datetime_conversion_for_condition(column)
|
133
|
-
case value['opt']
|
134
|
-
when 'RANGE'
|
135
|
-
values = date_bridge_from_to_for_range(column, value)
|
136
|
-
# Avoid calling to_time, not needed and broken on rails >= 4, because return local time instead of UTC
|
137
|
-
values.collect!(&conversion) if conversion != :to_time
|
138
|
-
values
|
139
|
-
when 'PAST', 'FUTURE'
|
140
|
-
values = date_bridge_from_to_for_trend(column, value)
|
141
|
-
# Avoid calling to_time, not needed and broken on rails >= 4, because return local time instead of UTC
|
142
|
-
values.collect!(&conversion) if conversion != :to_time
|
143
|
-
values
|
144
|
-
else
|
145
|
-
%w[from to].collect { |field| condition_value_for_datetime(column, value[field], conversion) }
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def date_bridge_now
|
150
|
-
Time.zone.now
|
151
|
-
end
|
152
|
-
|
153
|
-
def date_bridge_from_to_for_trend(column, value)
|
154
|
-
case value['opt']
|
155
|
-
when 'PAST'
|
156
|
-
trend_number = [value['number'].to_i, 1].max
|
157
|
-
now = date_bridge_now
|
158
|
-
if date_bridge_column_date?(column)
|
159
|
-
from = now.beginning_of_day.ago(trend_number.send(value['unit'].downcase.singularize.to_sym))
|
160
|
-
to = now.end_of_day
|
161
|
-
else
|
162
|
-
from = now.ago(trend_number.send(value['unit'].downcase.singularize.to_sym))
|
163
|
-
to = now
|
164
|
-
end
|
165
|
-
[from, to]
|
166
|
-
when 'FUTURE'
|
167
|
-
trend_number = [value['number'].to_i, 1].max
|
168
|
-
now = date_bridge_now
|
169
|
-
if date_bridge_column_date?(column)
|
170
|
-
from = now.beginning_of_day
|
171
|
-
to = now.end_of_day.in(trend_number.send(value['unit'].downcase.singularize.to_sym))
|
172
|
-
else
|
173
|
-
from = now
|
174
|
-
to = now.in(trend_number.send(value['unit'].downcase.singularize.to_sym))
|
175
|
-
end
|
176
|
-
[from, to]
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def date_bridge_from_to_for_range(column, value)
|
181
|
-
case value['range']
|
182
|
-
when 'TODAY'
|
183
|
-
[date_bridge_now.beginning_of_day, date_bridge_now.end_of_day]
|
184
|
-
when 'YESTERDAY'
|
185
|
-
[date_bridge_now.ago(1.day).beginning_of_day, date_bridge_now.ago(1.day).end_of_day]
|
186
|
-
when 'TOMORROW'
|
187
|
-
[date_bridge_now.in(1.day).beginning_of_day, date_bridge_now.in(1.day).end_of_day]
|
188
|
-
else
|
189
|
-
range_type, range = value['range'].downcase.split('_')
|
190
|
-
raise ArgumentError unless %w[week month year].include?(range)
|
191
|
-
case range_type
|
192
|
-
when 'this'
|
193
|
-
return date_bridge_now.send("beginning_of_#{range}".to_sym), date_bridge_now.send("end_of_#{range}")
|
194
|
-
when 'prev'
|
195
|
-
return date_bridge_now.ago(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), date_bridge_now.ago(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
|
196
|
-
when 'next'
|
197
|
-
return date_bridge_now.in(1.send(range.to_sym)).send("beginning_of_#{range}".to_sym), date_bridge_now.in(1.send(range.to_sym)).send("end_of_#{range}".to_sym)
|
198
|
-
else
|
199
|
-
return nil, nil
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
def date_bridge_column_date?(column)
|
205
|
-
if %i[date_picker datetime_picker].include? column.form_ui
|
206
|
-
column.form_ui == :date_picker
|
207
|
-
else
|
208
|
-
(!column.column.nil? && [:date].include?(column.column.type))
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
ActiveScaffold::Finder.const_set('DATE_COMPARATORS', %w[PAST FUTURE RANGE])
|
219
|
-
ActiveScaffold::Finder.const_set('DATE_UNITS', %w[DAYS WEEKS MONTHS YEARS])
|
220
|
-
ActiveScaffold::Finder.const_set('TIME_UNITS', %w[SECONDS MINUTES HOURS])
|
221
|
-
ActiveScaffold::Finder.const_set('DATE_RANGES', %w[TODAY YESTERDAY TOMORROW THIS_WEEK PREV_WEEK NEXT_WEEK THIS_MONTH PREV_MONTH NEXT_MONTH THIS_YEAR PREV_YEAR NEXT_YEAR])
|