effective_datatables 4.15.2 → 4.16.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 912f48109a916890adbbad18c1058045d815203f13bd130d5f152cd7fb831dcb
4
- data.tar.gz: 1e1438c39beed755b3c1d095d35568fa292c59680e1e60b1c79e775f88205419
3
+ metadata.gz: fb919d816894dbb8f980d70f0bcbe66706476bca2ceaa59c5a149b4c7342f23a
4
+ data.tar.gz: 0bf163d43e1ec174f76adedc190565f540a8191f33b5fa554093bf8a1be3398f
5
5
  SHA512:
6
- metadata.gz: 7720dd73963000639ee65ef9113182491ff8c485d19a6ce7e214b1af45efdca91ff9ff303e2c90450d0935543cdebe780ae5e441f69f1b7482e0355ddbf0da33
7
- data.tar.gz: 031335f7c000193c45caeff8d362267277ea0f19ded4e117eb7c00aee6ccfdbed31671d63c8f41648cfcf9d6b98719d7b90774d3d806fdfa10ce0d0a9fff0aee
6
+ metadata.gz: 8e847cb1063625374e346dea0b30e4c8b6416d2a73c0e7dcd330b27d4b4e8d61af9f8409565abedbdcf5185ea0d96fef6638a82c1c4f7c9c139020e10f6f2d1a
7
+ data.tar.gz: bb80cdb66df0055384d9c1021118590bd2c787c8fbf499fe7e5316b6c124a5d402c9f88196a2cb585a58f4dfac48f28df8f0ce052fdf31b829cff4c12461fbad
data/README.md CHANGED
@@ -50,6 +50,7 @@ Please check out [Effective Datatables 3.x](https://github.com/code-and-effect/e
50
50
  * [filters](#filters)
51
51
  * [scope](#scope)
52
52
  * [filter](#filter)
53
+ * [filter_date_range](#filter_date_range)
53
54
  * [bulk_actions](#bulk_actions)
54
55
  * [bulk_action](#bulk_action)
55
56
  * [bulk_action](#bulk_action_divider)
@@ -791,6 +792,24 @@ required: true|false # Passed to form
791
792
 
792
793
  Any other option given will be yielded to EffectiveBootstrap as options.
793
794
 
795
+ ## filter_date_range
796
+
797
+ There is also a special date range filter built in. To use:
798
+
799
+ ```ruby
800
+ filters do
801
+ filter_date_range
802
+ end
803
+
804
+ collection do
805
+ Things.where(updated_at: date_range)
806
+ end
807
+ ```
808
+
809
+ This method creates 3 filters, `filters[:date_range]`, `filters[:start_date]` and `filters[:end_date]` and presents a rough Prev/Next month and year navigation. Do not have any columns named the same as these.
810
+
811
+ You can pass a default into `filter_date_range`, one of `:current_month`, `:current_year`, `:month`, `:year` and `:custom`.
812
+
794
813
  ## bulk_actions
795
814
 
796
815
  Creates a single dropdown menu with a link to each action, download or content.
@@ -70,7 +70,7 @@ initializeDataTables = (target) ->
70
70
  params['scope'] = $form.find("input[name='filters[scope]']:checked").val() || ''
71
71
  params['filter'] = {}
72
72
 
73
- $form.find("select,textarea,input:not([type=submit])").each ->
73
+ $form.find("select,textarea,input:enabled:not([type=submit])").each ->
74
74
  $input = $(this)
75
75
 
76
76
  if ['utf8', 'authenticity_token', 'filters[scope]'].includes($input.attr('name'))
@@ -128,14 +128,16 @@ module EffectiveDatatablesPrivateHelper
128
128
  return unless datatable._scopes.present? || datatable._filters.present?
129
129
 
130
130
  if datatable._filters_form_required?
131
- render partial: 'effective/datatables/filters', locals: { datatable: datatable }
131
+ render('effective/datatables/filters', datatable: datatable)
132
132
  else
133
- render(partial: 'effective/datatables/filters', locals: { datatable: datatable }).gsub('<form', '<div').gsub('/form>', '/div>').html_safe
133
+ render('effective/datatables/filters', datatable: datatable).gsub('<form', '<div').gsub('/form>', '/div>').html_safe
134
134
  end
135
135
 
136
136
  end
137
137
 
138
138
  def datatable_filter_tag(form, datatable, name, opts)
139
+ return if opts[:visible] == false
140
+
139
141
  as = opts[:as].to_s.chomp('_field').to_sym
140
142
  value = datatable.state[:filter][name]
141
143
  collection = opts[:collection]
@@ -199,6 +199,33 @@ module Effective
199
199
  "#{self.class.name.underscore.parameterize}-#{[self.class, attributes].hash.abs.to_s.last(12)}"
200
200
  end
201
201
 
202
+ def date_range(value = nil)
203
+ now = Time.zone.now
204
+
205
+ value ||= filters[:date_range]
206
+ start_date ||= filters[:start_date]
207
+ end_date ||= filters[:end_date]
208
+
209
+ return (nil..nil) if value.blank?
210
+
211
+ case value.to_sym
212
+ when :current_month
213
+ (now.beginning_of_month..now.end_of_day)
214
+ when :current_year
215
+ (now.beginning_of_year..now.end_of_day)
216
+ when :month
217
+ (start_date || now).all_month
218
+ when :year
219
+ (start_date || now).all_year
220
+ when :custom
221
+ (start_date&.beginning_of_day..end_date&.end_of_day)
222
+ when :all
223
+ (nil..nil)
224
+ else
225
+ raise('unexpected date range value')
226
+ end
227
+ end
228
+
202
229
  def columns
203
230
  @_columns
204
231
  end
@@ -223,6 +250,10 @@ module Effective
223
250
  columns.values.inject({}) { |h, col| h[col[:index]] = col[:visible]; h }
224
251
  end
225
252
 
253
+ def filters_form
254
+ DatatableFiltersForm.new(datatable: self)
255
+ end
256
+
226
257
  private
227
258
 
228
259
  def column_tool
@@ -0,0 +1,21 @@
1
+ # Form Object for the filters form
2
+
3
+ module Effective
4
+ class DatatableFiltersForm
5
+ include ActiveModel::Model
6
+
7
+ attr_accessor :scope
8
+
9
+ def initialize(datatable:)
10
+ # Assign the current value of scope
11
+ assign_attributes(scope: datatable.state[:scope])
12
+
13
+ # Create an attr_accesor for each filter and assign value
14
+ datatable._filters.each do |name, options|
15
+ self.class.send(:attr_accessor, name)
16
+ assign_attributes(name => datatable.state[:filter][name])
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -4,6 +4,29 @@ module Effective
4
4
  module EffectiveDatatable
5
5
  module Dsl
6
6
  module Filters
7
+
8
+ DATE_RANGES = [
9
+ ['Current Month', :current_month],
10
+ ['Current Year', :current_year],
11
+ ['Month', :month],
12
+ ['Year', :year],
13
+ ['Custom', :custom]
14
+ ]
15
+
16
+ # This sets up the select field with start_on and end_on
17
+ def filter_date_range(default = nil)
18
+ if default.present?
19
+ valid = DATE_RANGES.map(&:last)
20
+ raise("unexpected value #{default}. Try one of #{valid.to_sentence}") unless valid.include?(default)
21
+ end
22
+
23
+ date_range = datatable.date_range(default)
24
+
25
+ filter :date_range, default, collection: DATE_RANGES, partial: 'effective/datatables/filter_date_range'
26
+ filter :start_date, date_range&.begin, as: :date, visible: false
27
+ filter :end_date, date_range&.end, as: :date, visible: false
28
+ end
29
+
7
30
  def filter(name = nil, value = :_no_value, as: nil, label: nil, parse: nil, required: false, **input_html)
8
31
  return datatable.filter if (name == nil && value == :_no_value) # This lets block methods call 'filter' and get the values
9
32
 
@@ -0,0 +1,51 @@
1
+ - name = '' unless datatable._filters_form_required?
2
+ - now = Time.zone.now.beginning_of_day
3
+
4
+ = f.select :date_range, opts[:collection], autocomplete: 'off', feedback: false, placeholder: 'All available dates'
5
+
6
+ .mx-2
7
+
8
+ - start_date = (f.object.start_date || now)
9
+ - end_date = (f.object.end_date || now)
10
+
11
+ - raise('expected a date start_date') unless start_date.respond_to?(:strftime)
12
+ - raise('expected a date end_date') unless end_date.respond_to?(:strftime)
13
+
14
+ - path = effective_datatables.datatable_path(datatable)
15
+
16
+ - prev_month = (start_date - 1.month).beginning_of_month
17
+ - next_month = (start_date + 1.month).beginning_of_month
18
+ - prev_year = (start_date - 1.year).beginning_of_year
19
+ - next_year = (start_date + 1.year).beginning_of_year
20
+
21
+ - prev_month_path = effective_datatables.datatable_path(datatable, date_range: :month, start_date: prev_month.strftime('%F'), end_date: prev_month.end_of_month.strftime('%F'))
22
+ - next_month_path = effective_datatables.datatable_path(datatable, date_range: :month, start_date: next_month.strftime('%F'), end_date: next_month.end_of_month.strftime('%F'))
23
+ - prev_year_path = effective_datatables.datatable_path(datatable, date_range: :year, start_date: prev_year.strftime('%F'), end_date: prev_year.end_of_year.strftime('%F'))
24
+ - next_year_path = effective_datatables.datatable_path(datatable, date_range: :year, start_date: next_year.strftime('%F'), end_date: next_year.end_of_month.strftime('%F'))
25
+
26
+ = f.show_if :date_range, :current_month do
27
+ = f.static_field :month do
28
+ #{now.beginning_of_month.strftime('%F')} to #{now.strftime('%F')} (today)
29
+
30
+ = f.show_if :date_range, :current_year do
31
+ = f.static_field :year do
32
+ #{now.beginning_of_year.strftime('%F')} to #{now.strftime('%F')} (today)
33
+
34
+ = f.show_if :date_range, :month do
35
+ = f.static_field :month do
36
+ = link_to((prev_month.strftime('%b %Y') + ' ' + icon('arrow-left-circle')).html_safe, prev_month_path.sub(path, request.path))
37
+ #{start_date.beginning_of_month.strftime('%F')} to #{start_date.end_of_month.strftime('%F')}
38
+ = link_to((icon('arrow-right-circle') + ' ' + next_month.strftime('%b %Y')).html_safe, next_month_path.sub(path, request.path))
39
+
40
+ = f.show_if :date_range, :year do
41
+ = f.static_field :year do
42
+ = link_to((prev_year.strftime('%Y') + ' ' + icon('arrow-left-circle')).html_safe, prev_year_path.sub(path, request.path))
43
+ #{start_date.beginning_of_year.strftime('%F')} to #{start_date.end_of_year.strftime('%F')}
44
+ = link_to((icon('arrow-right-circle') + ' ' + next_year.strftime('%Y')).html_safe, next_year_path.sub(path, request.path))
45
+
46
+ = f.show_if :date_range, :custom do
47
+ .row
48
+ .col
49
+ = f.date_field :start_date, name: name, autocomplete: 'off', feedback: false
50
+ .col
51
+ = f.date_field :end_date, name: name, autocomplete: 'off', feedback: false
@@ -1,11 +1,15 @@
1
1
  .effective-datatables-filters{'aria-controls': datatable.to_param}
2
- = effective_form_with(scope: :filters, url: (datatable._form[:url] || '#'), method: datatable._form[:verb], id: nil) do |form|
2
+
3
+ = effective_form_with(model: datatable.filters_form, scope: :filters, url: (datatable._form[:url] || '#'), method: datatable._form[:verb], id: nil) do |form|
3
4
  .form-row.align-items-center
4
5
  - if datatable._scopes.present?
5
6
  = datatable_scope_tag(form, datatable)
6
7
 
7
8
  - datatable._filters.each do |name, opts|
8
- = datatable_filter_tag(form, datatable, name, opts)
9
+ - if opts[:partial].present?
10
+ = render(opts[:partial], form: form, f: form, datatable: datatable, name: name, opts: opts)
11
+ - else
12
+ = datatable_filter_tag(form, datatable, name, opts)
9
13
 
10
14
  .form-group.col-auto
11
15
  - if datatable._filters_form_required?
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '4.15.2'.freeze
2
+ VERSION = '4.16.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_datatables
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.15.2
4
+ version: 4.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-02 00:00:00.000000000 Z
11
+ date: 2023-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -137,6 +137,7 @@ files:
137
137
  - app/models/effective/datatable_column.rb
138
138
  - app/models/effective/datatable_column_tool.rb
139
139
  - app/models/effective/datatable_dsl_tool.rb
140
+ - app/models/effective/datatable_filters_form.rb
140
141
  - app/models/effective/datatable_value_tool.rb
141
142
  - app/models/effective/effective_datatable/attributes.rb
142
143
  - app/models/effective/effective_datatable/collection.rb
@@ -159,6 +160,7 @@ files:
159
160
  - app/views/effective/datatables/_buttons.html.haml
160
161
  - app/views/effective/datatables/_chart.html.haml
161
162
  - app/views/effective/datatables/_datatable.html.haml
163
+ - app/views/effective/datatables/_filter_date_range.html.haml
162
164
  - app/views/effective/datatables/_filters.html.haml
163
165
  - app/views/effective/datatables/_reorder_column.html.haml
164
166
  - app/views/effective/datatables/_resource_column.html.haml