effective_datatables 4.9.4 → 4.10.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 +4 -4
- data/README.md +25 -0
- data/app/assets/javascripts/effective_datatables/download.js.coffee +10 -0
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +2 -8
- data/app/controllers/effective/datatables_controller.rb +32 -0
- data/app/helpers/effective_datatables_helper.rb +9 -5
- data/app/helpers/effective_datatables_private_helper.rb +2 -13
- data/app/models/effective/datatable.rb +13 -0
- data/app/models/effective/effective_datatable/compute.rb +4 -3
- data/app/models/effective/effective_datatable/csv.rb +55 -0
- data/app/models/effective/effective_datatable/dsl/datatable.rb +11 -2
- data/app/models/effective/effective_datatable/format.rb +28 -11
- data/app/views/effective/datatables/_buttons.html.haml +14 -0
- data/config/effective_datatables.rb +3 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/nl.yml +1 -0
- data/config/routes.rb +1 -0
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/effective_datatables.rb +1 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 173cdec1d403c8203a7f3d3701104a76d7fd8fb04843c4989180b351b5096264
|
4
|
+
data.tar.gz: 70da4dcc029e6f7ac2a2f0d7f896734c4036eea227dfd5ecb6354f1efa59f531
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 474ead17fcde2196a4bdf06cdfa02c9d23e1dc4345126d79bcdf4fa3aa9785a358cce6d54a062862f17ec33c618a908db703a1eaa94e847a87df42dfe738b816
|
7
|
+
data.tar.gz: 55570bbe0d91f0bcdb24d818368a3a4dce9be6ffc0d7a99327121d8204df62a56b6eecc61a1bbbb6bb89b1feff5e4ea6d293497bb571ffff640331f14076d8b2
|
data/README.md
CHANGED
@@ -46,6 +46,7 @@ Please check out [Effective Datatables 3.x](https://github.com/code-and-effect/e
|
|
46
46
|
* [order](#order)
|
47
47
|
* [reorder](#reorder)
|
48
48
|
* [aggregate](#aggregate)
|
49
|
+
* [download](#download)
|
49
50
|
* [filters](#filters)
|
50
51
|
* [scope](#scope)
|
51
52
|
* [filter](#filter)
|
@@ -681,6 +682,30 @@ end.aggregate { |values, column| distance_of_time_in_words(values.min, values.ma
|
|
681
682
|
|
682
683
|
In the above example, `values` is an Array containing all row's values for one column at a time.
|
683
684
|
|
685
|
+
## download
|
686
|
+
|
687
|
+
Add a Download button which streams a CSV file containing all rows and columns in the table's collection, ignoring any search, sort or filtering.
|
688
|
+
|
689
|
+
This is an opt-in feature.
|
690
|
+
|
691
|
+
To enable, please set `config.download = true` in your `config/initializers/effective_datatables.rb` file.
|
692
|
+
|
693
|
+
Once enabled, you can disable it on an individual table by:
|
694
|
+
|
695
|
+
```ruby
|
696
|
+
datatable do
|
697
|
+
download false
|
698
|
+
end
|
699
|
+
```
|
700
|
+
|
701
|
+
and you can exclude individual columns from being rendered on the CSV export
|
702
|
+
|
703
|
+
```ruby
|
704
|
+
col :first_name, csv: false
|
705
|
+
```
|
706
|
+
|
707
|
+
The column will still appear in the export, but the contents will be blank.
|
708
|
+
|
684
709
|
## filters
|
685
710
|
|
686
711
|
Creates a single form with fields for each `filter` and a single radio input field for all `scopes`.
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$(document).on 'click', '.dataTables_wrapper a.buttons-download', (event) ->
|
2
|
+
$button = $(event.currentTarget)
|
3
|
+
$table = $('#' + $button.attr('aria-controls'))
|
4
|
+
|
5
|
+
url = $table.data('source').replace('.json', '/download.csv')
|
6
|
+
attributes = 'attributes=' + encodeURIComponent($table.data('attributes'))
|
7
|
+
|
8
|
+
$button.attr('href', url + '?' + attributes)
|
9
|
+
|
10
|
+
setTimeout (=> $button.attr('href', 'download.csv')), 0
|
@@ -112,14 +112,8 @@ initializeDataTables = (target) ->
|
|
112
112
|
$table = $(api.table().node())
|
113
113
|
$buttons = $table.closest('.dataTables_wrapper').children().first().find('.dt-buttons')
|
114
114
|
|
115
|
-
if $table.data('
|
116
|
-
$buttons.prepend($table.data('
|
117
|
-
|
118
|
-
if $table.data('reorder')
|
119
|
-
$buttons.prepend($table.data('reorder'))
|
120
|
-
|
121
|
-
if $table.data('bulk-actions')
|
122
|
-
$buttons.prepend($table.data('bulk-actions'))
|
115
|
+
if $table.data('buttons-html')
|
116
|
+
$buttons.prepend($table.data('buttons-html'))
|
123
117
|
|
124
118
|
drawAggregates = ($table, aggregates) ->
|
125
119
|
$tfoot = $table.find('tfoot').first()
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
1
3
|
module Effective
|
2
4
|
class DatatablesController < ApplicationController
|
3
5
|
skip_log_page_views quiet: true if defined?(EffectiveLogging)
|
@@ -20,6 +22,36 @@ module Effective
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
25
|
+
def download
|
26
|
+
@datatable = EffectiveDatatables.find(params[:id], params[:attributes])
|
27
|
+
@datatable.view = view_context
|
28
|
+
|
29
|
+
EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
|
30
|
+
|
31
|
+
respond_to do |format|
|
32
|
+
format.csv do
|
33
|
+
headers.delete('Content-Length')
|
34
|
+
|
35
|
+
headers['X-Accel-Buffering'] = 'no'
|
36
|
+
headers['Cache-Control'] = 'no-cache'
|
37
|
+
headers["Content-Type"] = @datatable.csv_content_type
|
38
|
+
headers["Content-Disposition"] = %(attachment; filename="#{@datatable.csv_filename}")
|
39
|
+
headers['Last-Modified'] = Time.zone.now.ctime.to_s
|
40
|
+
|
41
|
+
self.response_body = @datatable.csv_stream
|
42
|
+
response.status = 200
|
43
|
+
end
|
44
|
+
|
45
|
+
# format.csv do
|
46
|
+
# send_data(@datatable.csv_file, filename: @datatable.csv_filename, type: @datatable.csv_content_type, disposition: 'attachment')
|
47
|
+
# end
|
48
|
+
|
49
|
+
format.all do
|
50
|
+
render(status: :unauthorized, body: 'Access Denied')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
23
55
|
def reorder
|
24
56
|
begin
|
25
57
|
@datatable = EffectiveDatatables.find(params[:id], params[:attributes])
|
@@ -1,15 +1,21 @@
|
|
1
1
|
# These are expected to be called by a developer. They are part of the datatables DSL.
|
2
2
|
module EffectiveDatatablesHelper
|
3
|
-
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, namespace: nil, pagination: true, search: true, simple: false, sort: true)
|
3
|
+
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, download: nil, entries: true, filters: true, inline: false, namespace: nil, pagination: true, search: true, simple: false, sort: true)
|
4
4
|
raise 'expected datatable to be present' unless datatable
|
5
5
|
raise 'expected input_js to be a Hash' unless input_js.kind_of?(Hash)
|
6
6
|
|
7
|
+
if download.nil?
|
8
|
+
download = (buttons && EffectiveDatatables.download)
|
9
|
+
end
|
10
|
+
|
7
11
|
if simple
|
8
|
-
buttons = charts = entries = filters = pagination = search = sort = false
|
12
|
+
buttons = charts = download = entries = filters = pagination = search = sort = false
|
9
13
|
end
|
10
14
|
|
11
15
|
datatable.attributes[:inline] = true if inline
|
12
16
|
datatable.attributes[:sortable] = false unless sort
|
17
|
+
datatable.attributes[:searchable] = false unless search
|
18
|
+
datatable.attributes[:downloadable] = false unless download
|
13
19
|
datatable.attributes[:namespace] = namespace if namespace
|
14
20
|
|
15
21
|
datatable.view ||= self
|
@@ -44,7 +50,7 @@ module EffectiveDatatablesHelper
|
|
44
50
|
'all-label' => I18n.t('effective_datatables.all'),
|
45
51
|
'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
|
46
52
|
'authenticity-token' => form_authenticity_token,
|
47
|
-
'
|
53
|
+
'buttons-html' => datatable_buttons(datatable),
|
48
54
|
'columns' => datatable_columns(datatable),
|
49
55
|
'default-visibility' => datatable.default_visibility.to_json,
|
50
56
|
'display-length' => datatable.display_length,
|
@@ -54,8 +60,6 @@ module EffectiveDatatablesHelper
|
|
54
60
|
'inline' => inline.to_s,
|
55
61
|
'language' => EffectiveDatatables.language(I18n.locale),
|
56
62
|
'options' => input_js.to_json,
|
57
|
-
'reset' => (datatable_reset(datatable) if search),
|
58
|
-
'reorder' => datatable_reorder(datatable),
|
59
63
|
'reorder-index' => (datatable.columns[:_reorder][:index] if datatable.reorder?).to_s,
|
60
64
|
'simple' => simple.to_s,
|
61
65
|
'spinner' => icon('spinner'), # effective_bootstrap
|
@@ -19,23 +19,12 @@ module EffectiveDatatablesPrivateHelper
|
|
19
19
|
end.to_json.html_safe
|
20
20
|
end
|
21
21
|
|
22
|
-
def datatable_bulk_actions(datatable)
|
23
|
-
if datatable._bulk_actions.present?
|
24
|
-
render(partial: '/effective/datatables/bulk_actions_dropdown', locals: { datatable: datatable }).gsub("'", '"').html_safe
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
22
|
def datatable_display_order(datatable)
|
29
23
|
((datatable.sortable? && datatable.order_index) ? [datatable.order_index, datatable.order_direction] : false).to_json.html_safe
|
30
24
|
end
|
31
25
|
|
32
|
-
def
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
def datatable_reorder(datatable)
|
37
|
-
return unless datatable.reorder? && EffectiveDatatables.authorized?(self, :update, datatable.collection_class)
|
38
|
-
link_to(content_tag(:span, t('effective_datatables.reorder')), '#', class: 'btn btn-link btn-sm buttons-reorder', disabled: true)
|
26
|
+
def datatable_buttons(datatable, search: true)
|
27
|
+
render('/effective/datatables/buttons', datatable: datatable, search: search).gsub("'", '"').html_safe
|
39
28
|
end
|
40
29
|
|
41
30
|
def datatable_new_resource_button(datatable, name, column)
|
@@ -30,6 +30,7 @@ module Effective
|
|
30
30
|
include Effective::EffectiveDatatable::Collection
|
31
31
|
include Effective::EffectiveDatatable::Compute
|
32
32
|
include Effective::EffectiveDatatable::Cookie
|
33
|
+
include Effective::EffectiveDatatable::Csv
|
33
34
|
include Effective::EffectiveDatatable::Format
|
34
35
|
include Effective::EffectiveDatatable::Hooks
|
35
36
|
include Effective::EffectiveDatatable::Params
|
@@ -140,6 +141,10 @@ module Effective
|
|
140
141
|
to_json[:recordsTotal] == 0
|
141
142
|
end
|
142
143
|
|
144
|
+
def to_csv
|
145
|
+
csv_file()
|
146
|
+
end
|
147
|
+
|
143
148
|
def to_json
|
144
149
|
@json ||= (
|
145
150
|
{
|
@@ -167,6 +172,14 @@ module Effective
|
|
167
172
|
!reorder? && attributes[:sortable] != false
|
168
173
|
end
|
169
174
|
|
175
|
+
def searchable?
|
176
|
+
attributes[:searchable] != false
|
177
|
+
end
|
178
|
+
|
179
|
+
def downloadable?
|
180
|
+
attributes[:downloadable] != false
|
181
|
+
end
|
182
|
+
|
170
183
|
# Whether the filters must be rendered as a <form> or we can keep the normal <div> behaviour
|
171
184
|
def _filters_form_required?
|
172
185
|
_form[:verb].present?
|
@@ -58,13 +58,14 @@ module Effective
|
|
58
58
|
finalize(col)
|
59
59
|
end
|
60
60
|
|
61
|
-
def arrayize(collection)
|
61
|
+
def arrayize(collection, csv: false)
|
62
62
|
collection.map do |obj|
|
63
63
|
columns.map do |name, opts|
|
64
|
-
if state[:visible][name] == false && (name != order_name) # Sort by invisible array column
|
64
|
+
if state[:visible][name] == false && !csv && (name != order_name) # Sort by invisible array column
|
65
|
+
BLANK
|
66
|
+
elsif csv && !opts[:csv]
|
65
67
|
BLANK
|
66
68
|
elsif opts[:compute]
|
67
|
-
|
68
69
|
if array_collection?
|
69
70
|
dsl_tool.instance_exec(obj, obj[opts[:index]], &opts[:compute])
|
70
71
|
else
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
module EffectiveDatatable
|
5
|
+
module Csv
|
6
|
+
|
7
|
+
def csv_filename
|
8
|
+
self.class.name.underscore.parameterize + '.csv'
|
9
|
+
end
|
10
|
+
|
11
|
+
def csv_content_type
|
12
|
+
'text/csv; charset=utf-8'
|
13
|
+
end
|
14
|
+
|
15
|
+
def csv_header
|
16
|
+
columns.map { |_, opts| opts[:label] || '' }
|
17
|
+
end
|
18
|
+
|
19
|
+
def csv_file
|
20
|
+
CSV.generate do |csv|
|
21
|
+
csv << csv_header()
|
22
|
+
|
23
|
+
collection.send(csv_collection_method) do |resources|
|
24
|
+
resources = arrayize(resources, csv: true)
|
25
|
+
format(resources, csv: true)
|
26
|
+
finalize(resources)
|
27
|
+
|
28
|
+
resources.each { |resource| csv << resource }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def csv_stream
|
34
|
+
EffectiveResources.with_resource_enumerator do |lines|
|
35
|
+
lines << CSV.generate_line(csv_header)
|
36
|
+
|
37
|
+
collection.public_send(csv_collection_method) do |resources|
|
38
|
+
resources = arrayize(resources, csv: true)
|
39
|
+
format(resources, csv: true)
|
40
|
+
finalize(resources)
|
41
|
+
|
42
|
+
resources.each { |resource| lines << CSV.generate_line(resource) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def csv_collection_method
|
50
|
+
(active_record_collection? ? :find_in_batches : :to_a)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -24,11 +24,15 @@ module Effective
|
|
24
24
|
reorder_col(name)
|
25
25
|
end
|
26
26
|
|
27
|
+
def download(bool)
|
28
|
+
datatable.attributes[:downloadable] = bool
|
29
|
+
end
|
30
|
+
|
27
31
|
# A col has its internal values sorted/searched before the block is run
|
28
32
|
# Anything done in the block, is purely a format on the after sorted/ordered value
|
29
33
|
# the original object == the computed value, which is yielded to the format block
|
30
34
|
# You can't do compute with .col
|
31
|
-
def col(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: nil, th: nil, th_append: nil, visible: true, &format)
|
35
|
+
def col(name, action: nil, as: nil, col_class: nil, csv: true, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: nil, th: nil, th_append: nil, visible: true, &format)
|
32
36
|
raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
|
33
37
|
|
34
38
|
name = name.to_sym unless name.to_s.include?('.')
|
@@ -38,6 +42,7 @@ module Effective
|
|
38
42
|
as: as,
|
39
43
|
compute: nil,
|
40
44
|
col_class: col_class,
|
45
|
+
csv: csv,
|
41
46
|
format: (format if block_given?),
|
42
47
|
index: nil,
|
43
48
|
label: (label.nil? ? name.to_s.split('.').last.titleize : label),
|
@@ -56,7 +61,7 @@ module Effective
|
|
56
61
|
|
57
62
|
# A val is a computed value that is then sorted/searched after the block is run
|
58
63
|
# You can have another block by calling .format afterwards to work on the computed value itself
|
59
|
-
def val(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: false, th: nil, th_append: nil, visible: true, &compute)
|
64
|
+
def val(name, action: nil, as: nil, col_class: nil, csv: true, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: false, th: nil, th_append: nil, visible: true, &compute)
|
60
65
|
raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
|
61
66
|
|
62
67
|
name = name.to_sym unless name.to_s.include?('.')
|
@@ -66,6 +71,7 @@ module Effective
|
|
66
71
|
as: as,
|
67
72
|
compute: (compute if block_given?),
|
68
73
|
col_class: col_class,
|
74
|
+
csv: csv,
|
69
75
|
format: nil,
|
70
76
|
index: nil,
|
71
77
|
label: (label.nil? ? name.to_s.split('.').last.titleize : label),
|
@@ -91,6 +97,7 @@ module Effective
|
|
91
97
|
compute: nil,
|
92
98
|
btn_class: (btn_class || 'btn-sm btn-outline-primary'),
|
93
99
|
col_class: col_class,
|
100
|
+
csv: false,
|
94
101
|
format: (format if block_given?),
|
95
102
|
index: nil,
|
96
103
|
inline: (inline.nil? ? datatable.inline? : inline),
|
@@ -130,6 +137,7 @@ module Effective
|
|
130
137
|
as: :bulk_actions,
|
131
138
|
compute: nil,
|
132
139
|
col_class: col_class,
|
140
|
+
csv: false,
|
133
141
|
format: nil,
|
134
142
|
index: nil,
|
135
143
|
input_name: (input_name || 'bulk_actions_resources'),
|
@@ -157,6 +165,7 @@ module Effective
|
|
157
165
|
as: :reorder,
|
158
166
|
compute: nil,
|
159
167
|
col_class: col_class,
|
168
|
+
csv: false,
|
160
169
|
format: nil,
|
161
170
|
index: nil,
|
162
171
|
label: false,
|
@@ -8,14 +8,16 @@ module Effective
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def format(collection)
|
11
|
+
def format(collection, csv: false)
|
12
12
|
# We want to use the render :collection for each column that renders partials
|
13
13
|
rendered = {}
|
14
14
|
|
15
15
|
columns.each do |name, opts|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
if state[:visible][name] == false && !csv
|
17
|
+
# Nothing to do
|
18
|
+
elsif csv && !opts[:csv]
|
19
|
+
# Nothing to do
|
20
|
+
elsif opts[:partial]
|
19
21
|
locals = { datatable: self, column: opts }.merge!(resource_col_locals(opts))
|
20
22
|
|
21
23
|
rendered[name] = (view.render(
|
@@ -26,6 +28,7 @@ module Effective
|
|
26
28
|
locals: locals,
|
27
29
|
spacer_template: SPACER_TEMPLATE
|
28
30
|
) || '').split(SPACER)
|
31
|
+
|
29
32
|
elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something'
|
30
33
|
locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE }
|
31
34
|
|
@@ -45,7 +48,6 @@ module Effective
|
|
45
48
|
else
|
46
49
|
(view.render_resource_actions(collection.map { |row| row[opts[:index]] }, atts, &opts[:format]) || '').split(SPACER)
|
47
50
|
end
|
48
|
-
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -54,9 +56,11 @@ module Effective
|
|
54
56
|
index = opts[:index]
|
55
57
|
value = row[index]
|
56
58
|
|
57
|
-
|
58
|
-
if state[:visible][name] == false
|
59
|
+
formatted = (
|
60
|
+
if state[:visible][name] == false && !csv
|
59
61
|
NONVISIBLE
|
62
|
+
elsif csv && !opts[:csv]
|
63
|
+
BLANK
|
60
64
|
elsif opts[:as] == :actions
|
61
65
|
rendered[name][row_index]
|
62
66
|
elsif opts[:format] && rendered.key?(name)
|
@@ -66,14 +70,23 @@ module Effective
|
|
66
70
|
elsif opts[:partial]
|
67
71
|
rendered[name][row_index]
|
68
72
|
else
|
69
|
-
format_column(value, opts)
|
73
|
+
format_column(value, opts, csv: csv)
|
70
74
|
end
|
71
75
|
)
|
76
|
+
|
77
|
+
if csv && (opts[:format] || opts[:partial])
|
78
|
+
formatted = view.strip_tags(formatted)
|
79
|
+
|
80
|
+
formatted.gsub!("\n\n", ' ') unless formatted.frozen?
|
81
|
+
formatted.gsub!("\n", '') unless formatted.frozen?
|
82
|
+
end
|
83
|
+
|
84
|
+
row[index] = formatted
|
72
85
|
end
|
73
86
|
end
|
74
87
|
end
|
75
88
|
|
76
|
-
def format_column(value, column)
|
89
|
+
def format_column(value, column, csv: false)
|
77
90
|
return if value.nil? || (column[:resource] && value.blank?)
|
78
91
|
|
79
92
|
unless column[:as] == :email
|
@@ -90,7 +103,11 @@ module Effective
|
|
90
103
|
when :date
|
91
104
|
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_date) : BLANK
|
92
105
|
when :datetime
|
93
|
-
|
106
|
+
if csv
|
107
|
+
value
|
108
|
+
else
|
109
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_datetime) : BLANK
|
110
|
+
end
|
94
111
|
when :decimal
|
95
112
|
value
|
96
113
|
when :duration
|
@@ -102,7 +119,7 @@ module Effective
|
|
102
119
|
when :effective_roles
|
103
120
|
value.join(', ')
|
104
121
|
when :email
|
105
|
-
view.mail_to(value)
|
122
|
+
csv ? value : view.mail_to(value)
|
106
123
|
when :integer
|
107
124
|
value
|
108
125
|
when :percent
|
@@ -0,0 +1,14 @@
|
|
1
|
+
- if datatable._bulk_actions.present?
|
2
|
+
= render('/effective/datatables/bulk_actions_dropdown', datatable: datatable)
|
3
|
+
|
4
|
+
- if datatable.searchable?
|
5
|
+
= link_to '#', class: 'btn btn-link btn-sm buttons-reset-search' do
|
6
|
+
%span= t('effective_datatables.reset')
|
7
|
+
|
8
|
+
- if datatable.reorder? && EffectiveDatatables.authorized?(self, :update, datatable.collection_class)
|
9
|
+
= link_to '#', class: 'btn btn-link btn-sm buttons-reorder' do
|
10
|
+
%span= t('effective_datatables.reorder')
|
11
|
+
|
12
|
+
- if datatable.downloadable?
|
13
|
+
= link_to 'download.csv', class: 'btn btn-link btn-sm buttons-download', 'aria-controls': datatable.to_param do
|
14
|
+
%span= t('effective_datatables.download')
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/locales/nl.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -2,6 +2,7 @@ EffectiveDatatables::Engine.routes.draw do
|
|
2
2
|
scope :module => 'effective' do
|
3
3
|
match 'datatables/:id(.:format)', to: 'datatables#show', via: [:get, :post], as: :datatable
|
4
4
|
match 'datatables/:id/reorder(.:format)', to: 'datatables#reorder', via: [:post], as: :reorder_datatable
|
5
|
+
match 'datatables/:id/download(.:format)', to: 'datatables#download', via: :get, as: :download_datatable
|
5
6
|
end
|
6
7
|
end
|
7
8
|
|
data/lib/effective_datatables.rb
CHANGED
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.
|
4
|
+
version: 4.10.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: 2021-
|
11
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- app/assets/javascripts/effective_datatables.js
|
112
112
|
- app/assets/javascripts/effective_datatables/bulk_actions.js.coffee
|
113
113
|
- app/assets/javascripts/effective_datatables/charts.js.coffee
|
114
|
+
- app/assets/javascripts/effective_datatables/download.js.coffee
|
114
115
|
- app/assets/javascripts/effective_datatables/events.js.coffee
|
115
116
|
- app/assets/javascripts/effective_datatables/filters.js.coffee
|
116
117
|
- app/assets/javascripts/effective_datatables/flash.js.coffee
|
@@ -141,6 +142,7 @@ files:
|
|
141
142
|
- app/models/effective/effective_datatable/collection.rb
|
142
143
|
- app/models/effective/effective_datatable/compute.rb
|
143
144
|
- app/models/effective/effective_datatable/cookie.rb
|
145
|
+
- app/models/effective/effective_datatable/csv.rb
|
144
146
|
- app/models/effective/effective_datatable/dsl.rb
|
145
147
|
- app/models/effective/effective_datatable/dsl/bulk_actions.rb
|
146
148
|
- app/models/effective/effective_datatable/dsl/charts.rb
|
@@ -154,6 +156,7 @@ files:
|
|
154
156
|
- app/views/effective/datatables/_active_storage_column.html.haml
|
155
157
|
- app/views/effective/datatables/_bulk_actions_column.html.haml
|
156
158
|
- app/views/effective/datatables/_bulk_actions_dropdown.html.haml
|
159
|
+
- app/views/effective/datatables/_buttons.html.haml
|
157
160
|
- app/views/effective/datatables/_chart.html.haml
|
158
161
|
- app/views/effective/datatables/_datatable.html.haml
|
159
162
|
- app/views/effective/datatables/_filters.html.haml
|