active_scaffold 3.7.0 → 3.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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])
|