effective_datatables 4.15.2 → 4.16.0

Sign up to get free protection for your applications and to get access to all the features.
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