agilibox 1.9.17 → 1.11.0

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/app/controllers/concerns/agilibox/api_controller_concern.rb +1 -1
  4. data/app/filters/agilibox/small_data/filter.rb +7 -1
  5. data/app/filters/agilibox/small_data/filter_strategy_by_date_begin.rb +1 -1
  6. data/app/filters/agilibox/small_data/filter_strategy_by_date_end.rb +1 -1
  7. data/app/helpers/agilibox/form_helper.rb +10 -0
  8. data/app/helpers/agilibox/pagination_helper.rb +9 -1
  9. data/app/models/concerns/agilibox/search.rb +2 -0
  10. data/app/serializers/agilibox/serializers/base.rb +6 -6
  11. data/app/serializers/agilibox/serializers/xlsx.rb +27 -1
  12. data/app/views/agilibox/search/_form_bs3.html.slim +1 -0
  13. data/app/views/agilibox/search/_form_bs4.html.slim +1 -0
  14. data/app/views/agilibox/search/_form_bs5.html.slim +8 -0
  15. data/app/views/kaminari/bootstrap4/_first_page.html.slim +2 -0
  16. data/app/views/kaminari/bootstrap4/_gap.html.slim +2 -0
  17. data/app/views/kaminari/bootstrap4/_last_page.html.slim +2 -0
  18. data/app/views/kaminari/bootstrap4/_next_page.html.slim +2 -0
  19. data/app/views/kaminari/bootstrap4/_page.html.slim +6 -0
  20. data/app/views/kaminari/bootstrap4/_paginator.html.slim +12 -0
  21. data/app/views/kaminari/bootstrap4/_prev_page.html.slim +2 -0
  22. data/lib/agilibox/active_model_custom_error_messages.rb +20 -5
  23. data/lib/agilibox/cucumber_helpers/capybara.rb +2 -1
  24. data/lib/agilibox/errors_middleware.rb +2 -0
  25. data/lib/agilibox/version.rb +1 -1
  26. metadata +25 -5
  27. data/app/filters/agilibox/small_data/filter_strategy_by_time_period.rb +0 -6
  28. data/app/serializers/agilibox/serializers/axlsx.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d915e06c7f404c90124074fbd3d6cd670b6a518f7e9bf770be57b3ff8578016c
4
- data.tar.gz: 4296515fd57d0d3d184dfb0907f32e4924afbc95e023cf210b6f2c4d3b87e08a
3
+ metadata.gz: 73e2e45e1fed7a2e0cec02d337dc0afa3bf0112e4b26ec3168d8b62e0f64c961
4
+ data.tar.gz: 9a79efe0583a84370cc71d57468e6083b77032053c59ae702c9c557a3cac3dd4
5
5
  SHA512:
6
- metadata.gz: 15a09252e2808322e8b764b0c48c2baf25574818af6d149dd35d7ab83c00ebc7738e8a4fada25bee183534fdeae3d5b01acc85bdc0673b56fe4f8bbd807beda7
7
- data.tar.gz: 5e2827c129f389a9a43ece6ec345784f589d0b609270a5f8730c85c89107c2d267c9aa2184f5e4d8f1b1ecae5865443ecb5a1438c6eac67679fb6d48bc8b63ae
6
+ metadata.gz: 80764451b386701e1e0033ed885589c1e95bff2bd973cc022dc706ce828fc86f1ac8c947c8bbe5b6f394e395fa5c1e9f933b45fb0173fe03d7ef3c088bc2eed2
7
+ data.tar.gz: 727f23e415b4aa280e2d96bc91d3016636e2e8f76a8a197218b9a8ef93797e638fb9637f880603293476c0ad6960fcd6d1974f74a1669184f20624f4b8169222
data/CHANGELOG.md CHANGED
@@ -2,6 +2,38 @@
2
2
 
3
3
  ## Next version
4
4
 
5
+ ## v1.11.0
6
+ - Add ActionDispatch::Http::MimeNegotiation::InvalidType to errors middleware
7
+ - Fix inverted forbidden/unauthorized
8
+
9
+ ## v1.10.5
10
+ - Fix hidden_inputs_for_get_form again
11
+
12
+ ## v1.10.4
13
+ - Fix hidden_inputs_for_get_form
14
+
15
+ ## v1.10.3
16
+ - Fix search forms to preserve GET params
17
+
18
+ ## v1.10.2
19
+ - Filters improvements
20
+
21
+ ## v1.10.1
22
+ - Fix date filters
23
+
24
+ ## v1.10.0
25
+ - Add date support to XLSX serializer
26
+ - Remove AXLSX serializer
27
+
28
+ ## v1.9.20
29
+ - Add bootstrap 5 search form
30
+
31
+ ## v1.9.19
32
+ - Add bootstrap 4/5 pagination support
33
+
34
+ ## v1.9.18
35
+ - Rails 6.1 compatibility
36
+
5
37
  ## v1.9.17
6
38
  - Fix capybara selector
7
39
 
@@ -54,7 +54,7 @@ module Agilibox::ApiControllerConcern
54
54
  end
55
55
 
56
56
  def render_forbidden_or_unauthorized
57
- current_user ? render_unauthorized : render_forbidden
57
+ current_user ? render_forbidden : render_unauthorized
58
58
  end
59
59
 
60
60
  included do |controller|
@@ -1,4 +1,6 @@
1
1
  class Agilibox::SmallData::Filter
2
+ include ActiveModel::Model
3
+
2
4
  STRATEGIES = {}
3
5
 
4
6
  attr_reader :jar
@@ -60,8 +62,12 @@ class Agilibox::SmallData::Filter
60
62
  write read.merge(new_filters)
61
63
  end
62
64
 
65
+ def actives_count
66
+ read.count { |k, v| strategies.key?(k.to_s) && v.present? }
67
+ end
68
+
63
69
  def any?
64
- read.select { |k, v| strategies.key?(k.to_s) && v.present? }.any?
70
+ actives_count.positive?
65
71
  end
66
72
 
67
73
  def empty?
@@ -1,6 +1,6 @@
1
1
  class Agilibox::SmallData::FilterStrategyByDateBegin < ::Agilibox::SmallData::FilterStrategyByKeyValue
2
2
  def apply(query, value)
3
- value = Time.zone.parse(value).beginning_of_day
3
+ value = Date.parse(value)
4
4
  column = column_for(query)
5
5
  query.where("#{column} >= ?", value)
6
6
  end
@@ -1,6 +1,6 @@
1
1
  class Agilibox::SmallData::FilterStrategyByDateEnd < ::Agilibox::SmallData::FilterStrategyByKeyValue
2
2
  def apply(query, value)
3
- value = Time.zone.parse(value).end_of_day
3
+ value = Date.parse(value)
4
4
  column = column_for(query)
5
5
  query.where("#{column} <= ?", value)
6
6
  end
@@ -59,4 +59,14 @@ module Agilibox::FormHelper
59
59
  :label => label,
60
60
  )
61
61
  end
62
+
63
+ def hidden_inputs_for_get_form(url, except: [])
64
+ query_values = Addressable::URI.parse(url).query_values.to_h
65
+ .with_indifferent_access
66
+ .except(*except)
67
+
68
+ return if query_values.empty?
69
+
70
+ query_values.sum { |k, v| tag.input(type: "hidden", name: k, value: v) }
71
+ end
62
72
  end
@@ -1,6 +1,14 @@
1
1
  module Agilibox::PaginationHelper
2
+ class << self
3
+ attr_writer :theme
4
+
5
+ def theme
6
+ @theme ||= "twitter-bootstrap-3"
7
+ end
8
+ end
9
+
2
10
  def paginate(objects, options = {})
3
- options = {theme: "twitter-bootstrap-3"}.merge(options)
11
+ options = {theme: Agilibox::PaginationHelper.theme}.merge(options)
4
12
  super(objects, **options).gsub(/>(\s+)</, "><").html_safe
5
13
  end
6
14
 
@@ -12,6 +12,8 @@ module Agilibox::Search
12
12
  words = q.to_s.parameterize.split("-")
13
13
  fields = default_search_fields if fields.empty?
14
14
 
15
+ return all if words.empty?
16
+
15
17
  sql_query = words.map.with_index { |_word, index|
16
18
  fields.map { |field|
17
19
  "(UNACCENT(CAST(#{field} AS TEXT)) ILIKE :w#{index})"
@@ -39,8 +39,8 @@ class Agilibox::Serializers::Base
39
39
  I18n.t(value.to_s)
40
40
  end
41
41
 
42
- def format_datetime(value)
43
- Agilibox::AllHelpers.date(value)
42
+ def format_date_or_time(value)
43
+ value
44
44
  end
45
45
 
46
46
  def format_default(value)
@@ -48,10 +48,10 @@ class Agilibox::Serializers::Base
48
48
  end
49
49
 
50
50
  def formatter_for(value)
51
- return :integer if value.is_a?(Integer)
52
- return :decimal if value.is_a?(Numeric)
53
- return :boolean if value.is_a?(TrueClass) || value.is_a?(FalseClass)
54
- return :datetime if value.is_a?(Date) || value.is_a?(Time)
51
+ return :integer if value.is_a?(Integer)
52
+ return :decimal if value.is_a?(Numeric)
53
+ return :boolean if value.is_a?(TrueClass) || value.is_a?(FalseClass)
54
+ return :date_or_time if value.is_a?(Date) || value.is_a?(Time)
55
55
  return :default
56
56
  end
57
57
 
@@ -1,7 +1,13 @@
1
1
  class Agilibox::Serializers::XLSX < Agilibox::Serializers::Base
2
2
  def render_inline
3
3
  headers, *data = formatted_data
4
- SpreadsheetArchitect.to_xlsx(headers: headers, data: data, freeze_headers: true)
4
+
5
+ SpreadsheetArchitect.to_xlsx(
6
+ headers: headers,
7
+ data: data,
8
+ freeze_headers: true,
9
+ range_styles: range_styles(data[0]),
10
+ )
5
11
  end
6
12
 
7
13
  def render_file(file_path)
@@ -9,4 +15,24 @@ class Agilibox::Serializers::XLSX < Agilibox::Serializers::Base
9
15
  f.write(render_inline)
10
16
  end
11
17
  end
18
+
19
+ private
20
+
21
+ def range_styles(row)
22
+ return [] if row.nil?
23
+
24
+ date_range_styles(row) + time_range_styles(row)
25
+ end
26
+
27
+ def date_range_styles(row)
28
+ row.each_index.select { row[_1].is_a?(Date) }.map do
29
+ {range: {rows: :all, columns: _1}, styles: {format_code: "dd/mm/yyyy"}}
30
+ end
31
+ end
32
+
33
+ def time_range_styles(row)
34
+ row.each_index.select { row[_1].is_a?(Time) }.map do
35
+ {range: {rows: :all, columns: _1}, styles: {format_code: "dd/mm/yyyy hh:mm:ss"}}
36
+ end
37
+ end
12
38
  end
@@ -1,4 +1,5 @@
1
1
  form.search.bs3 method="get" action=action
2
+ = hidden_inputs_for_get_form(action, except: [:q])
2
3
  = form_hidden_submit
3
4
 
4
5
  p.input-group.search
@@ -1,4 +1,5 @@
1
1
  form.search.bs4 method="get" action=action
2
+ = hidden_inputs_for_get_form(action, except: [:q])
2
3
  = form_hidden_submit
3
4
 
4
5
  .input-group.search
@@ -0,0 +1,8 @@
1
+ form.search.bs5.mb-3 method="get" action=action
2
+ = hidden_inputs_for_get_form(action, except: [:q])
3
+ = form_hidden_submit
4
+
5
+ .input-group.search
6
+ input.form-control.form-control-sm type="text" name="q" placeholder=ta(:search) value=params[:q]
7
+ button.btn.btn-sm.bg-light.border.search-reset.reset type="submit" = icon(:times)
8
+ button.btn.btn-sm.bg-light.border.search-submit type="submit" = icon(:search)
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item.disabled
2
+ = link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link'
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link'
@@ -0,0 +1,6 @@
1
+ - if page.current?
2
+ li.page-item.active
3
+ = content_tag :a, page, data: { remote: remote }, rel: page.rel, class: 'page-link'
4
+ - else
5
+ li.page-item
6
+ = link_to page, url, remote: remote, rel: page.rel, class: 'page-link'
@@ -0,0 +1,12 @@
1
+ = paginator.render do
2
+ nav
3
+ ul.pagination
4
+ == first_page_tag unless current_page.first?
5
+ == prev_page_tag unless current_page.first?
6
+ - each_page do |page|
7
+ - if page.left_outer? || page.right_outer? || page.inside_window?
8
+ == page_tag page
9
+ - elsif !page.was_truncated?
10
+ == gap_tag
11
+ == next_page_tag unless current_page.last?
12
+ == last_page_tag unless current_page.last?
@@ -0,0 +1,2 @@
1
+ li.page-item
2
+ = link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link'
@@ -1,8 +1,23 @@
1
1
  module Agilibox::ActiveModelCustomErrorMessages
2
- def full_message(attribute, message)
3
- return message[1..] if message[0] == "^"
4
- super(attribute, message)
2
+ # Rails <= 6.0
3
+ module ForErrors
4
+ def full_message(attribute, message)
5
+ return message[1..] if message[0] == "^"
6
+ super
7
+ end
8
+ end
9
+
10
+ ActiveModel::Errors.prepend(ForErrors)
11
+
12
+ # Rails >= 6.1
13
+ module ForError
14
+ def full_message
15
+ return message[1..] if message[0] == "^"
16
+ super
17
+ end
5
18
  end
6
- end
7
19
 
8
- ActiveModel::Errors.prepend(Agilibox::ActiveModelCustomErrorMessages)
20
+ if Module.const_defined?("ActiveModel::Error")
21
+ ActiveModel::Error.prepend(ForError)
22
+ end
23
+ end
@@ -1,5 +1,6 @@
1
1
  Capybara.register_driver :agilibox_no_driver do |_app|
2
- raise "You need to add Agilibox::CucumberConfig.require_cuprite! or "\
2
+ raise \
3
+ "You need to add Agilibox::CucumberConfig.require_cuprite! or " \
3
4
  "Agilibox::CucumberConfig.require_chrome_headless! " \
4
5
  "to your features/support/env.rb"
5
6
  end
@@ -9,6 +9,8 @@ class Agilibox::ErrorsMiddleware
9
9
  "ActionController::BadRequest",
10
10
  "ActionController::UnknownFormat",
11
11
  "ActionController::UnknownHttpMethod",
12
+ "ActionDispatch::Cookies::CookieOverflow",
13
+ "ActionDispatch::Http::MimeNegotiation::InvalidType",
12
14
  "ActionView::MissingTemplate",
13
15
  "Mime::Type::InvalidMimeType",
14
16
  ]
@@ -1,3 +1,3 @@
1
1
  module Agilibox
2
- VERSION = "1.9.17"
2
+ VERSION = "1.11.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agilibox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.17
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - agilidée
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-13 00:00:00.000000000 Z
11
+ date: 2021-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails-i18n
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: addressable
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: Agilibox
84
98
  email:
85
99
  - contact@agilidee.com
@@ -125,7 +139,6 @@ files:
125
139
  - app/filters/agilibox/small_data/filter_strategy_by_key_value.rb
126
140
  - app/filters/agilibox/small_data/filter_strategy_by_key_values.rb
127
141
  - app/filters/agilibox/small_data/filter_strategy_by_tags.rb
128
- - app/filters/agilibox/small_data/filter_strategy_by_time_period.rb
129
142
  - app/forms/agilibox/mini_form_object.rb
130
143
  - app/helpers/agilibox/all_helpers.rb
131
144
  - app/helpers/agilibox/bootstrap_helper.rb
@@ -163,7 +176,6 @@ files:
163
176
  - app/models/concerns/agilibox/search.rb
164
177
  - app/models/concerns/agilibox/timestamp_helpers.rb
165
178
  - app/serializers/agilibox/serializers.rb
166
- - app/serializers/agilibox/serializers/axlsx.rb
167
179
  - app/serializers/agilibox/serializers/base.rb
168
180
  - app/serializers/agilibox/serializers/xlsx.rb
169
181
  - app/services/agilibox/service.rb
@@ -179,6 +191,14 @@ files:
179
191
  - app/views/agilibox/search/_form.html.slim
180
192
  - app/views/agilibox/search/_form_bs3.html.slim
181
193
  - app/views/agilibox/search/_form_bs4.html.slim
194
+ - app/views/agilibox/search/_form_bs5.html.slim
195
+ - app/views/kaminari/bootstrap4/_first_page.html.slim
196
+ - app/views/kaminari/bootstrap4/_gap.html.slim
197
+ - app/views/kaminari/bootstrap4/_last_page.html.slim
198
+ - app/views/kaminari/bootstrap4/_next_page.html.slim
199
+ - app/views/kaminari/bootstrap4/_page.html.slim
200
+ - app/views/kaminari/bootstrap4/_paginator.html.slim
201
+ - app/views/kaminari/bootstrap4/_prev_page.html.slim
182
202
  - config/cucumber.yml
183
203
  - config/locales/actions.en.yml
184
204
  - config/locales/actions.fr.yml
@@ -244,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
264
  - !ruby/object:Gem::Version
245
265
  version: '0'
246
266
  requirements: []
247
- rubygems_version: 3.1.4
267
+ rubygems_version: 3.1.6
248
268
  signing_key:
249
269
  specification_version: 4
250
270
  summary: Agilibox
@@ -1,6 +0,0 @@
1
- class Agilibox::SmallData::FilterStrategyByTimePeriod
2
- def initialize(*)
3
- raise "FilterStrategyByTimePeriod is deprecated, please use " \
4
- "FilterStrategyByDatePeriod or FilterStrategyByDatetimePeriod"
5
- end
6
- end
@@ -1,21 +0,0 @@
1
- class Agilibox::Serializers::AXLSX < Agilibox::Serializers::Base
2
- def render_inline
3
- xlsx.to_stream.read.force_encoding("BINARY")
4
- end
5
-
6
- def render_file(file_path)
7
- xlsx.serialize(file_path)
8
- end
9
-
10
- def xlsx
11
- @xlsx ||= Axlsx::Package.new do |p|
12
- p.workbook.add_worksheet do |sheet|
13
- formatted_data.each do |line|
14
- sheet.add_row(line)
15
- end
16
- end
17
-
18
- p.use_shared_strings = true
19
- end
20
- end
21
- end