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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.rdoc +20 -0
  3. data/README.md +2 -0
  4. data/app/assets/javascripts/jquery/active_scaffold.js +68 -62
  5. data/app/assets/stylesheets/active_scaffold_layout.css +1 -1
  6. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +2 -1
  7. data/app/views/active_scaffold_overrides/_render_field.js.erb +9 -6
  8. data/config/locales/de.yml +6 -3
  9. data/config/locales/en.yml +3 -0
  10. data/config/locales/es.yml +3 -0
  11. data/config/locales/fr.yml +9 -6
  12. data/config/locales/hu.yml +20 -17
  13. data/config/locales/ja.yml +25 -22
  14. data/config/locales/ru.yml +17 -14
  15. data/lib/active_scaffold/actions/update.rb +3 -3
  16. data/lib/active_scaffold/attribute_params.rb +7 -17
  17. data/lib/active_scaffold/bridges/active_storage/form_ui.rb +6 -6
  18. data/lib/active_scaffold/bridges/active_storage/list_ui.rb +7 -7
  19. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +2 -2
  20. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +12 -14
  21. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +2 -2
  22. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
  23. data/lib/active_scaffold/bridges/chosen/helpers.rb +10 -10
  24. data/lib/active_scaffold/bridges/country_select/country_select_bridge_helper.rb +7 -7
  25. data/lib/active_scaffold/bridges/date_picker/ext.rb +20 -9
  26. data/lib/active_scaffold/bridges/date_picker/helper.rb +5 -5
  27. data/lib/active_scaffold/bridges/date_picker.rb +2 -0
  28. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +3 -3
  29. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +5 -5
  30. data/lib/active_scaffold/bridges/file_column/form_ui.rb +1 -1
  31. data/lib/active_scaffold/bridges/file_column/list_ui.rb +3 -3
  32. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +1 -1
  33. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +3 -3
  34. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
  35. data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -15
  36. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +6 -6
  37. data/lib/active_scaffold/bridges/usa_state_select/usa_state_select_helper.rb +5 -5
  38. data/lib/active_scaffold/bridges.rb +0 -3
  39. data/lib/active_scaffold/constraints.rb +22 -7
  40. data/lib/active_scaffold/core.rb +5 -3
  41. data/lib/active_scaffold/data_structures/column.rb +108 -23
  42. data/lib/active_scaffold/engine.rb +15 -0
  43. data/lib/active_scaffold/extensions/routing_mapper.rb +1 -0
  44. data/lib/active_scaffold/finder.rb +142 -27
  45. data/lib/active_scaffold/helpers/controller_helpers.rb +9 -4
  46. data/lib/active_scaffold/helpers/form_column_helpers.rb +114 -94
  47. data/lib/active_scaffold/helpers/human_condition_helpers.rb +48 -14
  48. data/lib/active_scaffold/helpers/list_column_helpers.rb +34 -18
  49. data/lib/active_scaffold/helpers/search_column_helpers.rb +131 -55
  50. data/lib/active_scaffold/helpers/show_column_helpers.rb +6 -6
  51. data/lib/active_scaffold/orm_checks.rb +21 -1
  52. data/lib/active_scaffold/version.rb +1 -1
  53. data/lib/active_scaffold.rb +3 -2
  54. data/test/bridges/date_picker_test.rb +3 -2
  55. data/test/bridges/paperclip_test.rb +3 -2
  56. data/test/bridges/tiny_mce_test.rb +4 -2
  57. data/test/helpers/form_column_helpers_test.rb +7 -5
  58. data/test/helpers/search_column_helpers_test.rb +2 -1
  59. data/test/misc/constraints_test.rb +1 -0
  60. data/test/misc/finder_test.rb +38 -0
  61. metadata +2 -6
  62. data/config/brakeman.ignore +0 -26
  63. data/config/brakeman.yml +0 -3
  64. data/config/i18n-tasks.yml +0 -121
  65. 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
- 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, :object => @record, :name => 'search[adult]', :value => '0')
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
@@ -17,6 +17,7 @@ module ModelStubs
17
17
  @table_name || to_s.split('::').last.underscore.pluralize
18
18
  end
19
19
  self.store_full_sti_class = false
20
+ def self.load_schema; end
20
21
  end
21
22
 
22
23
  ##
@@ -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.0
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-01-12 00:00:00.000000000 Z
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
@@ -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
@@ -1,3 +0,0 @@
1
- ---
2
- :run_all_checks: true
3
- :quiet: true
@@ -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, '&nbsp;'.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])