active_list 6.9.4 → 7.3.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 +5 -5
- data/app/assets/javascripts/active_list.jquery.js.coffee +6 -1
- data/app/assets/stylesheets/active_list/theme.scss +1 -1
- data/lib/active_list.rb +1 -0
- data/lib/active_list/definition/abstract_column.rb +2 -1
- data/lib/active_list/definition/action_column.rb +4 -4
- data/lib/active_list/definition/attribute_column.rb +21 -9
- data/lib/active_list/definition/empty_column.rb +4 -0
- data/lib/active_list/definition/status_column.rb +13 -0
- data/lib/active_list/definition/table.rb +4 -0
- data/lib/active_list/exporters/abstract_exporter.rb +34 -1
- data/lib/active_list/exporters/csv_exporter.rb +7 -3
- data/lib/active_list/exporters/excel_csv_exporter.rb +3 -3
- data/lib/active_list/exporters/open_document_spreadsheet_exporter.rb +35 -53
- data/lib/active_list/generator.rb +7 -5
- data/lib/active_list/generator/finder.rb +89 -6
- data/lib/active_list/helpers.rb +5 -4
- data/lib/active_list/renderers/simple_renderer.rb +82 -15
- data/lib/active_list/version.rb +1 -1
- data/test/dummy/Gemfile +7 -5
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/initializers/secret_token.rb +0 -1
- data/test/dummy/db/migrate/20120510131331_create_people.rb +1 -1
- data/test/dummy/db/migrate/20120510134500_create_contacts.rb +1 -1
- data/test/dummy/db/schema.rb +13 -14
- data/test/people_controller_test.rb +7 -7
- data/test/test_helper.rb +16 -0
- metadata +25 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 493c967944f09543ead6e2782c62bbf1379d7db9ce73aaf99a31a30ae7f7ef26
|
|
4
|
+
data.tar.gz: 5b06ebaf0f046687c035febfd6399d86c700ab15540aa8629faf30793889dc29
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abac2cf9a73fbb3ebcc26466e481178f4fb3645b30dbfb00dd01a807e84f6132d59b0bb3d4cd016ad9998cbc0c709c75012132f69fd9b4c434f4cb13adb7da9e
|
|
7
|
+
data.tar.gz: 8cf5cb483304b2da19a74b86ee1289a9d14612c640c6394f1bebed329498ddb4d2f7b9714d614db2df2813e45de7e5cebafd251cf38b988bcb0ff94ed709978f
|
|
@@ -23,7 +23,7 @@ ActiveList = {}
|
|
|
23
23
|
content = $(data)
|
|
24
24
|
list_data = content.find(".list-data")
|
|
25
25
|
list_control = content.find(".list-control")
|
|
26
|
-
for type in ["actions", "pagination", "settings"]
|
|
26
|
+
for type in ["actions", "pagination", "footer-pagination","settings"]
|
|
27
27
|
$("*[data-list-ref='#{list_id}'].list-#{type}").replaceWith list_control.find(".list-#{type}")
|
|
28
28
|
list.find(".list-data").html(list_data)
|
|
29
29
|
selection = list.prop('selection')
|
|
@@ -158,6 +158,11 @@ ActiveList = {}
|
|
|
158
158
|
|
|
159
159
|
# Select row
|
|
160
160
|
$(document).on "click", "*[data-list-source] td>input[data-list-selector]", (event) ->
|
|
161
|
+
mainCheckbox = $("input[data-list-selector]").first()
|
|
162
|
+
someChecked = $("*[data-list-source] td>input[data-list-selector]:checked").length > 0
|
|
163
|
+
someUnchecked = $("*[data-list-source] td>input[data-list-selector]:not(:checked)").length > 0
|
|
164
|
+
mainCheckbox.prop("indeterminate", someChecked && someUnchecked);
|
|
165
|
+
mainCheckbox.prop("checked", someChecked || !someUnchecked);
|
|
161
166
|
AL.select $(this)
|
|
162
167
|
true
|
|
163
168
|
|
data/lib/active_list.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
module ActiveList
|
|
2
2
|
module Definition
|
|
3
3
|
class AbstractColumn
|
|
4
|
-
attr_reader :table, :name, :id, :options
|
|
4
|
+
attr_reader :table, :name, :id, :options, :condition
|
|
5
5
|
|
|
6
6
|
def initialize(table, name, options = {})
|
|
7
7
|
@table = table
|
|
8
8
|
@name = name.to_sym
|
|
9
9
|
@options = options
|
|
10
10
|
@hidden = !!@options.delete(:hidden)
|
|
11
|
+
@condition = @options.delete(:condition)
|
|
11
12
|
@id = 'c' + @table.new_column_id # ActiveList.new_uid
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -94,8 +94,8 @@ module ActiveList
|
|
|
94
94
|
url[:redirect] ||= 'params[:redirect]'.c
|
|
95
95
|
url.delete_if { |_k, v| v.nil? }
|
|
96
96
|
cases << "#{record}.#{@name} == #{expected.inspect}\nlink_to(content_tag(:i) + h(#{url[:action].inspect}.t(scope: 'rest.actions'))"\
|
|
97
|
-
', {' + url.collect { |k, v| "#{k}: " + urlify(v, record) }.join(', ') + format + '}' \
|
|
98
|
-
", {class: '#{@name}'" + link_options + '}'\
|
|
97
|
+
', {' + url.collect { |k, v| "#{k}: " + urlify(k, v, record) }.join(', ') + format + '}' \
|
|
98
|
+
", {class: '#{@options[:icon_name] || @name}'" + link_options + '}'\
|
|
99
99
|
")\n"
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -108,8 +108,8 @@ module ActiveList
|
|
|
108
108
|
url[:id] = 'RECORD.id'.c if url[:id] == ID_PLACEHOLDER
|
|
109
109
|
url[:redirect] ||= 'params[:redirect]'.c
|
|
110
110
|
url.delete_if { |_k, v| v.nil? }
|
|
111
|
-
url = '{' + url.collect { |k, v| "#{k}: " + urlify(v, record) }.join(', ') + format + '}'
|
|
112
|
-
code = "{class: '#{@name}'" + link_options + '}'
|
|
111
|
+
url = '{' + url.collect { |k, v| "#{k}: " + urlify(k, v, record) }.join(', ') + format + '}'
|
|
112
|
+
code = "{class: '#{@options[:icon_name] || @name}'" + link_options + '}'
|
|
113
113
|
code = "link_to(content_tag(:i) + h(' ' + :#{action}.t(scope: 'rest.actions')), " + url + ', ' + code + ')'
|
|
114
114
|
end
|
|
115
115
|
if @options[:if]
|
|
@@ -11,13 +11,7 @@ module ActiveList
|
|
|
11
11
|
else
|
|
12
12
|
@label_method.to_s.gsub('human_', '').to_sym
|
|
13
13
|
end
|
|
14
|
-
|
|
15
|
-
@sort_column = if @table.model.columns_hash[@label_method.to_s]
|
|
16
|
-
@label_method
|
|
17
|
-
elsif @table.model.columns_hash[@name.to_s]
|
|
18
|
-
@name
|
|
19
|
-
end
|
|
20
|
-
end
|
|
14
|
+
@sort_column = get_sort_column
|
|
21
15
|
@computation_method = options[:on_select]
|
|
22
16
|
@column = @table.model.columns_hash[@label_method.to_s]
|
|
23
17
|
end
|
|
@@ -51,9 +45,27 @@ module ActiveList
|
|
|
51
45
|
code.c
|
|
52
46
|
end
|
|
53
47
|
|
|
48
|
+
def get_sort_column
|
|
49
|
+
selects = @table.options[:select] || {}
|
|
50
|
+
selects_label = selects.find { |sql_name, name| name.to_s == @label_method.to_s }&.last
|
|
51
|
+
selects_name = selects.find { |sql_name, name| name.to_s == @name.to_s }&.last
|
|
52
|
+
if (selects_label || selects_name) && options[:sort].blank?
|
|
53
|
+
sort_column = (selects_label || selects_name)
|
|
54
|
+
else
|
|
55
|
+
sort_column = options[:sort]
|
|
56
|
+
sort_column ||= if @table.model.columns_hash[@label_method.to_s]
|
|
57
|
+
@label_method
|
|
58
|
+
elsif @table.model.columns_hash[@name.to_s]
|
|
59
|
+
@name
|
|
60
|
+
end
|
|
61
|
+
sort_column &&= "#{@table.model.table_name}.#{sort_column}"
|
|
62
|
+
end
|
|
63
|
+
sort_column
|
|
64
|
+
end
|
|
65
|
+
|
|
54
66
|
# Returns the class name of the used model
|
|
55
67
|
def class_name
|
|
56
|
-
|
|
68
|
+
"RECORD.class.name.tableize".c
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
def sortable?
|
|
@@ -70,7 +82,7 @@ module ActiveList
|
|
|
70
82
|
end
|
|
71
83
|
|
|
72
84
|
def sort_expression
|
|
73
|
-
|
|
85
|
+
@sort_column
|
|
74
86
|
end
|
|
75
87
|
end
|
|
76
88
|
end
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
module ActiveList
|
|
2
2
|
module Definition
|
|
3
3
|
class StatusColumn < AttributeColumn
|
|
4
|
+
def initialize(table, name, options = {})
|
|
5
|
+
super
|
|
6
|
+
|
|
7
|
+
@tooltip_method = options.fetch(:tooltip_method, nil)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def tooltip_title_code(record, child)
|
|
11
|
+
c = if @tooltip_method.nil?
|
|
12
|
+
"#{record}.try(:human_status) || #{record}&.try(:human_state_name) || #{datum_value(record, child)}.to_s.capitalize"
|
|
13
|
+
else
|
|
14
|
+
"#{record}.#{@tooltip_method}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
4
17
|
end
|
|
5
18
|
end
|
|
6
19
|
end
|
|
@@ -103,6 +103,10 @@ module ActiveList
|
|
|
103
103
|
add :action, name, options
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
# Add a new method in Table which permit to define empty columns
|
|
107
|
+
def empty(name, options = {})
|
|
108
|
+
add :empty, name, options
|
|
109
|
+
end
|
|
106
110
|
# # Add a new method in Table which permit to define data columns
|
|
107
111
|
# def attribute(name, options = {})
|
|
108
112
|
# add :attribute, name, options
|
|
@@ -12,12 +12,39 @@ module ActiveList
|
|
|
12
12
|
'txt'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def file_name_code
|
|
16
|
+
"file_name = #{table.model.name}.model_name.human\n".c
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
def mime_type
|
|
16
20
|
Mime::TEXT
|
|
17
21
|
end
|
|
18
22
|
|
|
23
|
+
def generate_file_code(format)
|
|
24
|
+
code = file_name_code
|
|
25
|
+
if generator.export_class
|
|
26
|
+
code << generator.exportable_query_code
|
|
27
|
+
code << "#{generator.export_class}.perform_later(user: current_user,\n"
|
|
28
|
+
code << " query: query,\n"
|
|
29
|
+
code << " content: #{columns_to_hash},\n"
|
|
30
|
+
code << " file_name: file_name,\n"
|
|
31
|
+
code << " format: '#{format}',\n"
|
|
32
|
+
code << " file_extension: '#{file_extension}')\n"
|
|
33
|
+
code << "notify_success(:document_in_preparation)\n"
|
|
34
|
+
code << "redirect_to(:back)\n"
|
|
35
|
+
else
|
|
36
|
+
code << generate_data_code
|
|
37
|
+
code << send_data_code
|
|
38
|
+
end
|
|
39
|
+
code.c
|
|
40
|
+
end
|
|
41
|
+
|
|
19
42
|
def send_data_code
|
|
20
|
-
raise NotImplementedError
|
|
43
|
+
raise NotImplementedError.new("#{self.class.name}#send_data_code must be implemented in sub-classes.")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def generate_data_code
|
|
47
|
+
raise NotImplementedError.new("#{self.class.name}#generate_data_code must be implemented in sub-classes.")
|
|
21
48
|
end
|
|
22
49
|
|
|
23
50
|
def columns_headers(options = {})
|
|
@@ -46,6 +73,12 @@ module ActiveList
|
|
|
46
73
|
end
|
|
47
74
|
array
|
|
48
75
|
end
|
|
76
|
+
|
|
77
|
+
def columns_to_hash
|
|
78
|
+
table.exportable_columns.map do |column|
|
|
79
|
+
[column.header_code, column.exporting_datum_code('record').to_s]
|
|
80
|
+
end.to_h
|
|
81
|
+
end
|
|
49
82
|
end
|
|
50
83
|
end
|
|
51
84
|
end
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
module ActiveList
|
|
2
2
|
module Exporters
|
|
3
3
|
class CsvExporter < AbstractExporter
|
|
4
|
+
|
|
4
5
|
def file_extension
|
|
5
6
|
'csv'
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
def mime_type
|
|
9
|
-
Mime
|
|
10
|
+
Mime[:csv]
|
|
10
11
|
end
|
|
11
12
|
|
|
12
|
-
def
|
|
13
|
+
def generate_data_code
|
|
13
14
|
record = 'r'
|
|
14
15
|
code = generator.select_data_code(paginate: false)
|
|
15
16
|
code << "data = ::CSV.generate do |csv|\n"
|
|
@@ -18,9 +19,12 @@ module ActiveList
|
|
|
18
19
|
code << " csv << [#{columns_to_array(:body, record: record).join(', ')}]\n"
|
|
19
20
|
code << " end\n"
|
|
20
21
|
code << "end\n"
|
|
21
|
-
code << "send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i, '_') + '.#{file_extension}')\n"
|
|
22
22
|
code.c
|
|
23
23
|
end
|
|
24
|
+
|
|
25
|
+
def send_data_code
|
|
26
|
+
"send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: file_name.parameterize + '.#{file_extension}')\n".c
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
end
|
|
26
30
|
end
|
|
@@ -4,15 +4,16 @@ Mime::Type.register('text/csv', :xcsv) unless defined? Mime::XCSV
|
|
|
4
4
|
module ActiveList
|
|
5
5
|
module Exporters
|
|
6
6
|
class ExcelCsvExporter < CsvExporter
|
|
7
|
+
|
|
7
8
|
def file_extension
|
|
8
9
|
'csv'
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def mime_type
|
|
12
|
-
Mime
|
|
13
|
+
Mime[:xcsv]
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
def
|
|
16
|
+
def generate_data_code
|
|
16
17
|
record = 'r'
|
|
17
18
|
code = generator.select_data_code(paginate: false)
|
|
18
19
|
encoding = 'CP1252'
|
|
@@ -22,7 +23,6 @@ module ActiveList
|
|
|
22
23
|
code << " csv << [#{columns_to_array(:body, record: record, encoding: encoding).join(', ')}]\n"
|
|
23
24
|
code << " end\n"
|
|
24
25
|
code << "end\n"
|
|
25
|
-
code << "send_data(data, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i,'_')+'.#{file_extension}')\n"
|
|
26
26
|
code.c
|
|
27
27
|
end
|
|
28
28
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# encoding: UTF-8
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'rodf'
|
|
4
4
|
|
|
5
5
|
# Register ODS format unless is already set
|
|
6
6
|
Mime::Type.register('application/vnd.oasis.opendocument.spreadsheet', :ods) unless defined? Mime::ODS
|
|
@@ -8,69 +8,51 @@ Mime::Type.register('application/vnd.oasis.opendocument.spreadsheet', :ods) unle
|
|
|
8
8
|
module ActiveList
|
|
9
9
|
module Exporters
|
|
10
10
|
class OpenDocumentSpreadsheetExporter < AbstractExporter
|
|
11
|
-
DATE_ELEMENTS = {
|
|
12
|
-
'm' => '<number:month number:style="long"/>',
|
|
13
|
-
'd' => '<number:day number:style="long"/>',
|
|
14
|
-
'Y' => '<number:year/>'
|
|
15
|
-
}.freeze
|
|
16
11
|
|
|
17
12
|
def file_extension
|
|
18
13
|
'ods'
|
|
19
14
|
end
|
|
20
15
|
|
|
21
16
|
def mime_type
|
|
22
|
-
Mime
|
|
17
|
+
Mime[:ods]
|
|
23
18
|
end
|
|
24
19
|
|
|
25
|
-
def
|
|
26
|
-
xml_escape = "to_s.gsub('&', '&').gsub('\\'', ''').gsub('<', '<').gsub('>', '>')"
|
|
27
|
-
xml_escape << ".force_encoding('US-ASCII')" if xml_escape.respond_to?(:force_encoding)
|
|
20
|
+
def generate_data_code
|
|
28
21
|
record = 'r'
|
|
29
|
-
code = generator.select_data_code(paginate: false)
|
|
30
|
-
code << "name = #{table.model.name}.model_name.human.gsub(/[^a-z0-9]/i, '_')\n"
|
|
31
|
-
code << "file = ActiveList.temporary_directory.join(name + rand(999_999_999).to_s(36) + '.#{file_extension}')\n"
|
|
32
|
-
code << "FileUtils.mkdir_p(file.dirname)\n"
|
|
33
|
-
code << "Zip::OutputStream.open(file) do |zile|\n"
|
|
34
|
-
# MimeType in first place
|
|
35
|
-
code << " zile.put_next_entry('mimetype', nil, nil, Zip::Entry::STORED)\n"
|
|
36
|
-
code << " zile << '#{mime_type}'\n"
|
|
37
|
-
|
|
38
|
-
# Manifest
|
|
39
|
-
code << " zile.put_next_entry('META-INF/manifest.xml')\n"
|
|
40
|
-
code << " zile << ('<?xml version=\"1.0\" encoding=\"UTF-8\"?><manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\"><manifest:file-entry manifest:media-type=\"#{mime_type}\" manifest:full-path=\"/\"/><manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/></manifest:manifest>')\n"
|
|
41
|
-
code << " zile.put_next_entry('content.xml')\n"
|
|
42
22
|
|
|
43
|
-
code
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
code = generator.select_data_code(paginate: false)
|
|
24
|
+
code << <<~RUBY
|
|
25
|
+
records = #{generator.records_variable_name}
|
|
26
|
+
data = RODF::Spreadsheet.new
|
|
27
|
+
|
|
28
|
+
data.instance_eval do
|
|
29
|
+
office_style :head, family: :cell do
|
|
30
|
+
property :text, 'font-weight': :bold
|
|
31
|
+
property :paragraph, 'text-align': :center
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
table #{table.model.name}.model_name.human do
|
|
35
|
+
row do
|
|
36
|
+
#{columns_to_array(:header)}.each do |header|
|
|
37
|
+
cell header, style: :head
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
for #{record} in records
|
|
42
|
+
row do
|
|
43
|
+
#{columns_to_array(:body, record: record)}.each do |value|
|
|
44
|
+
cell value
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
RUBY
|
|
51
|
+
code.c
|
|
52
|
+
end
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
code << " zile << ('<table:table-column table:number-columns-repeated=\"#{table.exportable_columns.size}\"/>')\n"
|
|
54
|
-
code << " zile << ('<table:table-header-rows><table:table-row>" + columns_headers.collect { |h| "<table:table-cell table:style-name=\"header\" office:value-type=\"string\"><text:p>'+(#{h}).#{xml_escape}+'</text:p></table:table-cell>" }.join + "</table:table-row></table:table-header-rows>')\n"
|
|
55
|
-
code << " for #{record} in #{generator.records_variable_name}\n"
|
|
56
|
-
code << " zile << ('<table:table-row>" + table.exportable_columns.collect do |column|
|
|
57
|
-
'<table:table-cell' + (if column.numeric? || column.datatype == :decimal
|
|
58
|
-
" office:value-type=\"float\" office:value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
|
59
|
-
elsif column.datatype == :boolean
|
|
60
|
-
" office:value-type=\"boolean\" office:boolean-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
|
61
|
-
elsif column.datatype == :date
|
|
62
|
-
" office:value-type=\"date\" table:style-name=\"ce1\" office:date-value=\"'+(#{column.datum_code(record)}).#{xml_escape}+'\""
|
|
63
|
-
else
|
|
64
|
-
' office:value-type="string"'
|
|
65
|
-
end) + "><text:p>'+(" + column.exporting_datum_code(record, true) + ").#{xml_escape}+'</text:p></table:table-cell>"
|
|
66
|
-
end.join + "</table:table-row>')\n"
|
|
67
|
-
code << " end\n"
|
|
68
|
-
code << " zile << ('</table:table></office:spreadsheet></office:body></office:document-content>')\n"
|
|
69
|
-
code << "end\n"
|
|
70
|
-
code << "send_file(file, stream: false, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: name+'.#{file_extension}')\n"
|
|
71
|
-
# code << "File.delete(file)\n" # Removes tmp files before they explode the disk
|
|
72
|
-
# raise code
|
|
73
|
-
code
|
|
54
|
+
def send_data_code
|
|
55
|
+
"send_data(data.bytes, type: #{mime_type.to_s.inspect}, disposition: 'inline', filename: file_name.parameterize + '.#{file_extension}')\n".c
|
|
74
56
|
end
|
|
75
57
|
end
|
|
76
58
|
end
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
module ActiveList
|
|
2
2
|
class Generator
|
|
3
|
-
attr_accessor :table, :controller, :controller_method_name, :view_method_name, :records_variable_name
|
|
3
|
+
attr_accessor :table, :controller, :controller_method_name, :view_method_name, :records_variable_name, :export_class
|
|
4
4
|
|
|
5
5
|
def initialize(*args, &_block)
|
|
6
6
|
options = args.extract_options!
|
|
7
7
|
@controller = options[:controller]
|
|
8
8
|
name = args.shift || @controller.controller_name.to_sym
|
|
9
9
|
model = (options[:model] || name).to_s.classify.constantize
|
|
10
|
-
@collection = !!(model.name == @controller.controller_name.to_s.classify)
|
|
10
|
+
@collection = options[:collection] || !!(model.name == @controller.controller_name.to_s.classify)
|
|
11
11
|
@controller_method_name = "list#{'_' + name.to_s if name != @controller.controller_name.to_sym}"
|
|
12
12
|
@view_method_name = "_#{@controller.controller_name}_list_#{name}_tag"
|
|
13
13
|
@records_variable_name = "@#{name}"
|
|
14
14
|
@table = ActiveList::Definition::Table.new(name, model, options)
|
|
15
|
+
@export_class = options[:export_class]
|
|
15
16
|
if block_given?
|
|
16
17
|
yield @table
|
|
17
18
|
else
|
|
@@ -47,7 +48,7 @@ module ActiveList
|
|
|
47
48
|
code << " end\n"
|
|
48
49
|
for format, exporter in ActiveList::Exporters.hash
|
|
49
50
|
code << " format.#{format} do\n"
|
|
50
|
-
code << exporter.new(self).
|
|
51
|
+
code << exporter.new(self).generate_file_code(format).dig(3)
|
|
51
52
|
code << " end\n"
|
|
52
53
|
end
|
|
53
54
|
code << " end\n"
|
|
@@ -70,7 +71,7 @@ module ActiveList
|
|
|
70
71
|
code = "# encoding: utf-8\n"
|
|
71
72
|
code << "def #{view_method_name}(options={}, &block)\n"
|
|
72
73
|
code << session_initialization_code.dig
|
|
73
|
-
code <<
|
|
74
|
+
code << "#{renderer.build_table_code}(options).dig\n"
|
|
74
75
|
code << "end\n"
|
|
75
76
|
# code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
|
|
76
77
|
unless ::Rails.env.production?
|
|
@@ -83,7 +84,8 @@ module ActiveList
|
|
|
83
84
|
|
|
84
85
|
def session_initialization_code
|
|
85
86
|
code = "options = {} unless options.is_a? Hash\n"
|
|
86
|
-
|
|
87
|
+
# For Rails 5
|
|
88
|
+
code << "options.update(params.to_unsafe_h)\n"
|
|
87
89
|
if defined?(User) && User.instance_methods.include?(:preference)
|
|
88
90
|
code << "#{var_name(:params)} = YAML::load(current_user.preference('list.#{view_method_name}', YAML::dump({})).value).symbolize_keys\n"
|
|
89
91
|
code << "#{var_name(:params)} = {} unless #{var_name(:params)}.is_a?(Hash)\n"
|
|
@@ -10,13 +10,14 @@ module ActiveList
|
|
|
10
10
|
@table.options[:order] = (columns.any? ? columns.first.name.to_sym : { id: :desc })
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
class_name = @table.model.name
|
|
14
|
-
class_name = "(controller_name != '#{class_name.tableize}' ? controller_name.to_s.classify.constantize : #{class_name})" if collection?
|
|
13
|
+
class_name = "options[\"constant_name\"]&.constantize || #{@table.model.name}"
|
|
14
|
+
class_name = "(controller_name != '#{class_name.tableize}' && !options[\"constant_name\"] ? controller_name.to_s.classify.constantize : #{class_name})" if collection?
|
|
15
15
|
|
|
16
16
|
# Find data
|
|
17
17
|
query_code = class_name.to_s
|
|
18
18
|
query_code << scope_code if scope_code
|
|
19
19
|
query_code << ".select(#{select_code})" if select_code
|
|
20
|
+
query_code << ".from(#{from_code})" if from_code
|
|
20
21
|
query_code << ".where(#{conditions_code})" unless @table.options[:conditions].blank?
|
|
21
22
|
query_code << ".joins(#{@table.options[:joins].inspect})" unless @table.options[:joins].blank?
|
|
22
23
|
unless includes_reflections.empty?
|
|
@@ -26,8 +27,14 @@ module ActiveList
|
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
code = ''
|
|
29
|
-
code << "#{
|
|
30
|
+
code << "#{query_code}\n"
|
|
30
31
|
|
|
32
|
+
code << if @table.options[:count].present?
|
|
33
|
+
"#{var_name(:count)} = #{query_code}.count(#{@table.options[:count].inspect})\n"
|
|
34
|
+
else
|
|
35
|
+
"#{var_name(:count)} = #{query_code}.count\n"
|
|
36
|
+
end
|
|
37
|
+
query_code << ".group(#{@table.options[:group].inspect})" unless @table.options[:group].blank?
|
|
31
38
|
query_code << ".reorder(#{var_name(:order)})"
|
|
32
39
|
|
|
33
40
|
if paginate
|
|
@@ -57,6 +64,64 @@ module ActiveList
|
|
|
57
64
|
code
|
|
58
65
|
end
|
|
59
66
|
|
|
67
|
+
def exportable_query_code(options = {})
|
|
68
|
+
unless @table.options.keys.include?(:order)
|
|
69
|
+
columns = @table.table_columns
|
|
70
|
+
@table.options[:order] = (columns.any? ? columns.first.name.to_sym : { id: :desc })
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class_name = "options[\"constant_name\"]&.constantize || #{@table.model.name}"
|
|
74
|
+
class_name = "(controller_name != '#{class_name.tableize}' && !options[\"constant_name\"] ? controller_name.to_s.classify.constantize : #{class_name})" if collection?
|
|
75
|
+
|
|
76
|
+
code = ''
|
|
77
|
+
|
|
78
|
+
code << "query = #{class_name}.to_s\n"
|
|
79
|
+
code << "query << #{scope_code.inspect}\n" if scope_code
|
|
80
|
+
|
|
81
|
+
if select_code
|
|
82
|
+
code << "select = #{select_code}\n"
|
|
83
|
+
code << "query << \".select(\"\n"
|
|
84
|
+
code << "query << select.inspect\n"
|
|
85
|
+
code << "query << \")\"\n"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
if from_code
|
|
89
|
+
code << "from = #{from_code}\n"
|
|
90
|
+
code << "query << \".from(\"\n"
|
|
91
|
+
code << "query << from.inspect\n"
|
|
92
|
+
code << "query << \")\"\n"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
unless @table.options[:conditions].blank?
|
|
96
|
+
code << "condition = #{conditions_code}\n"
|
|
97
|
+
code << "query << \".where(\"\n"
|
|
98
|
+
code << "query << condition.inspect\n"
|
|
99
|
+
code << "query << \")\"\n"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
code << "query << \".joins(#{@table.options[:joins].inspect})\"\n" unless @table.options[:joins].blank?
|
|
103
|
+
|
|
104
|
+
unless includes_reflections.empty?
|
|
105
|
+
expr = includes_reflections.inspect[1..-2]
|
|
106
|
+
code << "query << \".includes(#{expr})\"\n"
|
|
107
|
+
code << "query << \".references(#{expr})\"\n"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
unless @table.options[:group].blank?
|
|
111
|
+
code << "group = #{@table.options[:group].inspect}\n"
|
|
112
|
+
code << "query << \".group(\"\n"
|
|
113
|
+
code << "query << group.inspect\n"
|
|
114
|
+
code << "query << \")\"\n"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
code << "order = #{var_name(:order)}\n"
|
|
118
|
+
code << "query << \".reorder(\"\n"
|
|
119
|
+
code << "query << order.inspect\n"
|
|
120
|
+
code << "query << \")\"\n"
|
|
121
|
+
|
|
122
|
+
code.c
|
|
123
|
+
end
|
|
124
|
+
|
|
60
125
|
protected
|
|
61
126
|
|
|
62
127
|
# Compute includes Hash
|
|
@@ -111,15 +176,33 @@ module ActiveList
|
|
|
111
176
|
code
|
|
112
177
|
end
|
|
113
178
|
|
|
179
|
+
def from_code
|
|
180
|
+
return nil unless @table.options[:from]
|
|
181
|
+
from = @table.options[:from]
|
|
182
|
+
code = ''
|
|
183
|
+
code << '(' + from.gsub(/\s*\n\s*/, ';') + ')'
|
|
184
|
+
code
|
|
185
|
+
end
|
|
186
|
+
|
|
114
187
|
def select_code
|
|
115
188
|
return nil unless @table.options[:distinct] || @table.options[:select]
|
|
116
189
|
code = ''
|
|
117
190
|
code << 'DISTINCT ' if @table.options[:distinct]
|
|
118
|
-
code << "#{@table.model.table_name}.*"
|
|
119
191
|
if @table.options[:select]
|
|
120
|
-
code << @table.options[:select].collect { |k, v| ", #{k[0].to_s + '.' + k[1].to_s} AS #{v}" }.join
|
|
192
|
+
# code << @table.options[:select].collect { |k, v| ", #{k[0].to_s + '.' + k[1].to_s} AS #{v}" }.join
|
|
193
|
+
code << @table.options[:select].collect do |k, v|
|
|
194
|
+
c = if k.is_a? Array
|
|
195
|
+
k[0].to_s + '.' + k[1].to_s
|
|
196
|
+
else
|
|
197
|
+
k
|
|
198
|
+
end
|
|
199
|
+
c += " AS #{v}" unless v.blank?
|
|
200
|
+
c
|
|
201
|
+
end.join(', ')
|
|
202
|
+
else
|
|
203
|
+
code << "#{@table.model.table_name}.*"
|
|
121
204
|
end
|
|
122
|
-
("'
|
|
205
|
+
('"' + code + '"').c
|
|
123
206
|
end
|
|
124
207
|
|
|
125
208
|
def sanitize_condition(value)
|
data/lib/active_list/helpers.rb
CHANGED
|
@@ -20,11 +20,12 @@ module ActiveList
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def urlify(value, record_name)
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
def urlify(key, value, record_name, namespace = nil)
|
|
24
|
+
return value.inspect unless value.is_a?(CodeString)
|
|
25
|
+
if key == :controller && namespace
|
|
26
|
+
'(' + "'/#{namespace}/' + " + value.gsub(/RECORD/, record_name) + ')'
|
|
26
27
|
else
|
|
27
|
-
value.
|
|
28
|
+
'(' + value.gsub(/RECORD/, record_name) + ')'
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
end
|
|
@@ -34,14 +34,16 @@ module ActiveList
|
|
|
34
34
|
code
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def build_table_code
|
|
37
|
+
def build_table_code(options = {})
|
|
38
38
|
record = 'r'
|
|
39
39
|
|
|
40
40
|
# colgroup = columns_definition_code
|
|
41
41
|
header = header_code
|
|
42
42
|
extras = extras_codes
|
|
43
43
|
|
|
44
|
-
code = generator.select_data_code
|
|
44
|
+
code = "#{generator.select_data_code}(options)\n"
|
|
45
|
+
# Hack for Rails 5
|
|
46
|
+
code << "__params = params.permit!\n"
|
|
45
47
|
code << "#{var_name(:tbody)} = '<tbody data-total=\"' + #{var_name(:count)}.to_s + '\""
|
|
46
48
|
if table.paginate?
|
|
47
49
|
code << " data-per-page=\"' + #{var_name(:limit)}.to_s + '\""
|
|
@@ -51,11 +53,17 @@ module ActiveList
|
|
|
51
53
|
code << "if #{var_name(:count)} > 0\n"
|
|
52
54
|
code << " #{generator.records_variable_name}.each do |#{record}|\n"
|
|
53
55
|
code << " #{var_name(:attrs)} = {id: 'r' + #{record}.id.to_s}\n"
|
|
56
|
+
code << " if #{var_name(:params)}[:data]\n"
|
|
57
|
+
code << " #{var_name(:params)}[:data] = [#{var_name(:params)}[:data]] unless #{var_name(:params)}[:data].is_a?(Array)\n"
|
|
58
|
+
code << " #{var_name(:params)}[:data].each do |attr|\n"
|
|
59
|
+
code << " #{var_name(:attrs)}['data-' + attr.gsub('_', '-')] = #{record}.send(attr)\n"
|
|
60
|
+
code << " end\n"
|
|
61
|
+
code << " end\n"
|
|
54
62
|
if table.options[:line_class]
|
|
55
63
|
code << " #{var_name(:attrs)}[:class] = (#{recordify!(table.options[:line_class], record)}).to_s\n"
|
|
56
|
-
code << " #{var_name(:attrs)}[:class] << ' focus' if
|
|
64
|
+
code << " #{var_name(:attrs)}[:class] << ' focus' if __params['#{table.name}-id'].to_i == #{record}.id\n"
|
|
57
65
|
else
|
|
58
|
-
code << " #{var_name(:attrs)}[:class] = 'focus' if
|
|
66
|
+
code << " #{var_name(:attrs)}[:class] = 'focus' if __params['#{table.name}-id'].to_i == #{record}.id\n"
|
|
59
67
|
end
|
|
60
68
|
code << " #{var_name(:tbody)} << content_tag(:tr, #{var_name(:attrs)}) do\n"
|
|
61
69
|
code << columns_to_cells(:body, record: record).dig(3)
|
|
@@ -107,6 +115,7 @@ module ActiveList
|
|
|
107
115
|
code << "options[:content_for] ||= {}\n"
|
|
108
116
|
code << "#{var_name(:extras)} = ''\n"
|
|
109
117
|
extras.each do |name, ecode|
|
|
118
|
+
next if name == :footer_pagination
|
|
110
119
|
code << "if options[:content_for][:#{name}]\n"
|
|
111
120
|
code << " content_for(options[:content_for][:#{name}], (#{ecode}).html_safe)\n"
|
|
112
121
|
code << "else\n"
|
|
@@ -127,10 +136,21 @@ module ActiveList
|
|
|
127
136
|
code << "end\n"
|
|
128
137
|
code << "#{var_name(:content)} << #{var_name(:tbody)}\n"
|
|
129
138
|
code << "#{var_name(:content)} << '</table></div>'\n"
|
|
139
|
+
|
|
140
|
+
if table.options[:footer_pagination]
|
|
141
|
+
code << " footer_code = ''\n"
|
|
142
|
+
code << " if options[:content_for][:footer_pagination]\n"
|
|
143
|
+
code << " footer_code << content_for(options[:content_for][:pagination])\n"
|
|
144
|
+
code << " else\n"
|
|
145
|
+
code << " footer_code << (#{extras[:footer_pagination]})\n"
|
|
146
|
+
code << " end\n"
|
|
147
|
+
code << " #{var_name(:content)} << content_tag(:div, (footer_code).html_safe, class: 'list-control') unless footer_code.blank?\n"
|
|
148
|
+
end
|
|
149
|
+
|
|
130
150
|
# code << "return #{var_name(:content)}.html_safe if options[:only] == 'content'\n"
|
|
131
151
|
|
|
132
152
|
# Build whole
|
|
133
|
-
code << "return ('<div id=\"#{uid}\" data-list-source=\"'+h(url_for(options.merge(:action => '#{generator.controller_method_name}')))+'\" data-list-redirect=\"' +
|
|
153
|
+
code << "return ('<div id=\"#{uid}\" data-list-source=\"'+h(url_for(options.merge(:action => '#{generator.controller_method_name}')))+'\" data-list-redirect=\"' + __params[:redirect].to_s + '\" class=\"active-list\">' + #{var_name(:content)} + '</div>').html_safe\n"
|
|
134
154
|
# File.open('debug-activelist', 'w') { |file| file.write code }
|
|
135
155
|
code
|
|
136
156
|
end
|
|
@@ -150,17 +170,20 @@ module ActiveList
|
|
|
150
170
|
children_mode = !!(nature == :children)
|
|
151
171
|
for column in table.columns
|
|
152
172
|
value_code = ''
|
|
173
|
+
title_value_code = ''
|
|
153
174
|
if column.is_a? ActiveList::Definition::EmptyColumn
|
|
154
175
|
value_code = 'nil'
|
|
155
176
|
elsif column.is_a? ActiveList::Definition::StatusColumn
|
|
156
|
-
|
|
177
|
+
title_value_code = nil
|
|
157
178
|
value_code = column.datum_code(record, children_mode)
|
|
179
|
+
title_code = column.tooltip_title_code(record, children_mode)
|
|
158
180
|
levels = %w[go caution stop]
|
|
159
181
|
lights = levels.collect do |light|
|
|
160
182
|
"content_tag(:span, '', :class => #{light.inspect})"
|
|
161
183
|
end.join(' + ')
|
|
162
184
|
# Expected value are :valid, :warning, :error
|
|
163
|
-
|
|
185
|
+
|
|
186
|
+
value_code = "content_tag(:span, #{lights}, :class => 'lights lights-' + (#{levels.inspect}.include?(#{value_code}.to_s) ? #{value_code}.to_s : 'undefined'), data: { toggle: :tooltip, placement: :top }, title: #{title_code})"
|
|
164
187
|
|
|
165
188
|
elsif column.is_a? ActiveList::Definition::DataColumn
|
|
166
189
|
if column.options[:children].is_a?(FalseClass) && children_mode
|
|
@@ -168,6 +191,7 @@ module ActiveList
|
|
|
168
191
|
else
|
|
169
192
|
value_code = column.datum_code(record, children_mode)
|
|
170
193
|
if column.datatype == :boolean
|
|
194
|
+
title_value_code = value_code
|
|
171
195
|
value_code = "content_tag(:div, '', :class => 'checkbox-'+(" + value_code.to_s + " ? 'true' : 'false'))"
|
|
172
196
|
elsif %i[date datetime timestamp measure].include? column.datatype
|
|
173
197
|
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)"
|
|
@@ -179,7 +203,7 @@ module ActiveList
|
|
|
179
203
|
currency = :currency if currency.is_a?(TrueClass)
|
|
180
204
|
# currency = "#{record}.#{currency}".c if currency.is_a?(Symbol)
|
|
181
205
|
currency = "#{column.record_expr(record)}.#{currency}".c if currency.is_a?(Symbol)
|
|
182
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l(currency: #{currency.inspect}))"
|
|
206
|
+
value_code = "(#{value_code}.nil? || #{value_code}.zero? ? ('#{column.options[:default]}'.present? ? '#{column.options[:default]}' : '') : #{value_code}.l(currency: #{currency.inspect}))"
|
|
183
207
|
elsif column.datatype == :decimal
|
|
184
208
|
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)"
|
|
185
209
|
elsif column.enumerize?
|
|
@@ -189,15 +213,21 @@ module ActiveList
|
|
|
189
213
|
column.options[:url] = {} unless column.options[:url].is_a?(Hash)
|
|
190
214
|
column.options[:url][:id] ||= (column.record_expr(record) + '.id').c
|
|
191
215
|
column.options[:url][:action] ||= :show
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
216
|
+
default_controller = column.class_name.is_a?(CodeString) ? column.class_name : column.class_name.tableize.to_sym
|
|
217
|
+
column.options[:url][:controller] ||= default_controller
|
|
218
|
+
namespace = column.options[:url].delete(:namespace)
|
|
219
|
+
url = column.options[:url].collect { |k, v| "#{k}: " + urlify(k, v, record, namespace) }.join(', ')
|
|
220
|
+
|
|
221
|
+
title_value_code = value_code
|
|
195
222
|
value_code = "(#{value_code}.blank? ? '' : link_to(#{value_code}.to_s, #{url}))"
|
|
196
223
|
elsif column.options[:mode] || column.label_method == :email
|
|
224
|
+
title_value_code = value_code
|
|
197
225
|
value_code = "(#{value_code}.blank? ? '' : mail_to(#{value_code}))"
|
|
198
226
|
elsif column.options[:mode] || column.label_method == :website
|
|
227
|
+
title_value_code = value_code
|
|
199
228
|
value_code = "(#{value_code}.blank? ? '' : link_to(" + value_code + ', ' + value_code + '))'
|
|
200
229
|
elsif column.label_method == :color
|
|
230
|
+
title_value_code = value_code
|
|
201
231
|
value_code = "content_tag(:div, #{column.datum_code(record)}, style: 'background: #'+" + column.datum_code(record) + ')'
|
|
202
232
|
elsif column.label_method.to_s.match(/(^|\_)currency$/) && column.datatype == :string
|
|
203
233
|
value_code = "(Nomen::Currency[#{value_code}] ? Nomen::Currency[#{value_code}].human_name : #{value_code})"
|
|
@@ -207,11 +237,13 @@ module ActiveList
|
|
|
207
237
|
value_code = "(Nomen::Country[#{value_code}] ? (image_tag('countries/' + #{value_code}.to_s + '.png') + ' ' + Nomen::Country[#{value_code}].human_name).html_safe : #{value_code})"
|
|
208
238
|
else # if column.datatype == :string
|
|
209
239
|
value_code = "h(#{value_code}.to_s)"
|
|
240
|
+
title_value_code = nil
|
|
210
241
|
end
|
|
211
242
|
|
|
212
243
|
value_code = "if #{record}\n#{value_code.dig}end" if column.is_a?(ActiveList::Definition::AssociationColumn)
|
|
213
244
|
end
|
|
214
245
|
elsif column.is_a?(ActiveList::Definition::CheckBoxColumn)
|
|
246
|
+
title_value_code = nil
|
|
215
247
|
if nature == :body
|
|
216
248
|
form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c
|
|
217
249
|
value = 'nil'
|
|
@@ -226,15 +258,26 @@ module ActiveList
|
|
|
226
258
|
value_code << 'nil'
|
|
227
259
|
end
|
|
228
260
|
elsif column.is_a?(ActiveList::Definition::TextFieldColumn)
|
|
261
|
+
title_value_code = nil
|
|
229
262
|
form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c
|
|
230
263
|
value_code = (nature == :body ? "text_field_tag(#{form_name.inspect}, #{recordify!(column.options[:value] || column.name, record)}#{column.options[:size] ? ', size: ' + column.options[:size].to_s : ''})" : 'nil') # , id: '#{table.name}_'+#{record}.id.to_s + '_#{column.name}'
|
|
231
264
|
elsif column.is_a?(ActiveList::Definition::ActionColumn)
|
|
265
|
+
title_value_code = nil
|
|
232
266
|
next unless column.use_single?
|
|
233
267
|
value_code = (nature == :body ? column.operation(record) : 'nil')
|
|
234
268
|
else
|
|
235
269
|
value_code = "' ∅ '.html_safe"
|
|
236
270
|
end
|
|
237
|
-
|
|
271
|
+
|
|
272
|
+
title_attr_code = if title_value_code.nil?
|
|
273
|
+
''
|
|
274
|
+
elsif title_value_code.blank?
|
|
275
|
+
":title => (#{value_code}),"
|
|
276
|
+
else
|
|
277
|
+
":title => (#{title_value_code}),"
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
code << "content_tag(:td, #{title_attr_code} :class => \"#{column_classes(column)}\","
|
|
238
281
|
code << " data: { 'list-column-header' => '#{column.short_id}'"
|
|
239
282
|
code << ", 'list-cell-value' => \"\#{#{column.datum_value(record, children_mode)}.to_f}\"" if column.computable?
|
|
240
283
|
code << " } ) do\n"
|
|
@@ -282,7 +325,7 @@ module ActiveList
|
|
|
282
325
|
menu << '<li class="separator"></li>'
|
|
283
326
|
# Exports
|
|
284
327
|
ActiveList.exporters.each do |format, _exporter|
|
|
285
|
-
menu << "<li class=\"export export-#{format}\">' + link_to(content_tag(:i) + h('list.export_as'.t(exported: :#{format}.t(scope: 'list.export.formats'))),
|
|
328
|
+
menu << "<li class=\"export export-#{format}\">' + link_to(content_tag(:i) + h('list.export_as'.t(exported: :#{format}.t(scope: 'list.export.formats'))), __params.merge(action: :#{generator.controller_method_name}, sort: #{var_name(:params)}[:sort], dir: #{var_name(:params)}[:dir], format: '#{format}')) + '</li>"
|
|
286
329
|
end
|
|
287
330
|
menu << '</ul></span>'
|
|
288
331
|
menu
|
|
@@ -299,7 +342,7 @@ module ActiveList
|
|
|
299
342
|
end
|
|
300
343
|
table.columns.each do |column|
|
|
301
344
|
next if column.is_a?(ActiveList::Definition::ActionColumn) && !column.use_single?
|
|
302
|
-
code << "<th data-list-column=\"#{column.sort_id}\""
|
|
345
|
+
code << "<th data-list-column=\"#{column.options[:icon_name] || column.sort_id}\""
|
|
303
346
|
code << " data-list-column-cells=\"#{column.short_id}\""
|
|
304
347
|
code << " data-list-column-sort=\"'+(#{var_name(:params)}[:sort] != '#{column.sort_id}' ? 'asc' : #{var_name(:params)}[:dir] == 'asc' ? 'desc' : 'asc')+'\"" if column.sortable?
|
|
305
348
|
code << " data-list-column-computation=\"#{column.computation_method}\"" if column.computable?
|
|
@@ -368,6 +411,26 @@ module ActiveList
|
|
|
368
411
|
|
|
369
412
|
code << "'#{pagination}'"
|
|
370
413
|
codes[:pagination] = "'#{pagination}'"
|
|
414
|
+
|
|
415
|
+
if table.options[:footer_pagination]
|
|
416
|
+
pagination = ''
|
|
417
|
+
current_page = var_name(:page).to_s
|
|
418
|
+
last_page = var_name(:last).to_s
|
|
419
|
+
|
|
420
|
+
pagination << "<span class=\"list-footer-pagination\" data-list-ref=\"#{uid}\">"
|
|
421
|
+
pagination << "<span class=\"status\">' + 'list.pagination.x_to_y_of_total'.t(x: (#{var_name(:offset)} + (#{var_name(:count)} > 0 ? 1 : 0)), y: ((#{var_name(:last)} == #{var_name(:page)}) ? #{var_name(:count)} : #{var_name(:offset)} + #{var_name(:limit)}), total: #{var_name(:count)}) + '</span>"
|
|
422
|
+
|
|
423
|
+
pagination << '<span class="paginator">'
|
|
424
|
+
pagination << "<a href=\"#\" data-list-move-to-page=\"' + (#{current_page} - 1).to_s + '\" class=\"btn previous-page\"' + (#{current_page} != 1 ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.previous') + '</a>"
|
|
425
|
+
|
|
426
|
+
pagination << "<a href=\"#\" data-list-move-to-page=\"' + (#{current_page} + 1).to_s + '\" class=\"btn next-page\"' + (#{current_page} != #{last_page} ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.next')+'</a>"
|
|
427
|
+
pagination << '</span>'
|
|
428
|
+
|
|
429
|
+
pagination << '</span>'
|
|
430
|
+
|
|
431
|
+
code << "'#{pagination}'"
|
|
432
|
+
codes[:footer_pagination] = "'#{pagination}'"
|
|
433
|
+
end
|
|
371
434
|
end
|
|
372
435
|
codes
|
|
373
436
|
end
|
|
@@ -389,7 +452,11 @@ module ActiveList
|
|
|
389
452
|
classes = []
|
|
390
453
|
conds = []
|
|
391
454
|
conds << [:sor, "#{var_name(:params)}[:sort] == '#{column.sort_id}'".c] if column.sortable?
|
|
392
|
-
|
|
455
|
+
if column.is_a? ActiveList::Definition::DataColumn
|
|
456
|
+
conds << [:hidden, "#{var_name(:params)}[:hidden_columns].include?(:#{column.name})".c]
|
|
457
|
+
elsif column.condition
|
|
458
|
+
conds << [:hidden, "h(#{column.condition}) == 'false'".c]
|
|
459
|
+
end
|
|
393
460
|
classes << column.options[:class].to_s.strip unless column.options[:class].blank?
|
|
394
461
|
classes << column.short_id unless without_id
|
|
395
462
|
if column.is_a? ActiveList::Definition::ActionColumn
|
data/lib/active_list/version.rb
CHANGED
data/test/dummy/Gemfile
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
gem 'rails', '
|
|
3
|
+
gem 'rails', '~> 5.0'
|
|
4
4
|
|
|
5
5
|
# Bundle edge Rails instead:
|
|
6
6
|
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
|
7
7
|
|
|
8
|
-
gem 'sqlite3'
|
|
8
|
+
gem 'sqlite3', '~> 1.3.6'
|
|
9
9
|
gem 'active_list', path: '../..'
|
|
10
10
|
|
|
11
|
+
gem 'sprockets', '< 4'
|
|
12
|
+
|
|
11
13
|
# Gems used only for assets and not required
|
|
12
14
|
# in production environments by default.
|
|
13
15
|
group :assets do
|
|
14
|
-
gem 'sass-rails'
|
|
15
|
-
gem 'coffee-rails'
|
|
16
|
+
gem 'sass-rails'
|
|
17
|
+
gem 'coffee-rails'
|
|
16
18
|
|
|
17
19
|
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
18
20
|
gem 'therubyracer', platform: :ruby
|
|
19
21
|
|
|
20
|
-
gem 'uglifier'
|
|
22
|
+
gem 'uglifier'
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
gem 'jquery-rails'
|
|
@@ -39,6 +39,7 @@ module Dummy
|
|
|
39
39
|
# Configure sensitive parameters which will be filtered from the log file.
|
|
40
40
|
config.filter_parameters += [:password]
|
|
41
41
|
|
|
42
|
+
config.active_record.sqlite3.represent_boolean_as_integer = true
|
|
42
43
|
# Use SQL instead of Active Record's schema dumper when creating the database.
|
|
43
44
|
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
|
44
45
|
# like if you have constraints or database-specific column types
|
|
@@ -5,4 +5,3 @@
|
|
|
5
5
|
# Make sure the secret is at least 30 characters and all random,
|
|
6
6
|
# no regular words or you'll be exposed to dictionary attacks.
|
|
7
7
|
Dummy::Application.config.secret_key_base = '7a06e73398090c095bed02f2dff3808b043e50cb928f7b7bfd02faadd988a0d9cf31dfc74d1bf661ac94c8d0d73c8ceb4d98210d09f251f0c6d70f09923db784'
|
|
8
|
-
Dummy::Application.config.secret_token = '7a06e73398090c095bed02f2dff3808b043e50cb928f7b7bfd02faadd988a0d9cf31dfc74d1bf661ac94c8d0d73c8ceb4d98210d09f251f0c6d70f09923db784'
|
data/test/dummy/db/schema.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# encoding: UTF-8
|
|
2
1
|
# This file is auto-generated from the current state of the database. Instead
|
|
3
2
|
# of editing this file, please use the migrations feature of Active Record to
|
|
4
3
|
# incrementally modify your database, and then regenerate this schema definition.
|
|
@@ -11,26 +10,26 @@
|
|
|
11
10
|
#
|
|
12
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
13
12
|
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
|
13
|
+
ActiveRecord::Schema.define(version: 2012_05_10_134500) do
|
|
15
14
|
|
|
16
15
|
create_table "contacts", force: :cascade do |t|
|
|
17
|
-
t.integer
|
|
18
|
-
t.text
|
|
19
|
-
t.string
|
|
20
|
-
t.string
|
|
21
|
-
t.string
|
|
16
|
+
t.integer "person_id"
|
|
17
|
+
t.text "address"
|
|
18
|
+
t.string "phone"
|
|
19
|
+
t.string "fax"
|
|
20
|
+
t.string "country"
|
|
22
21
|
t.datetime "created_at", null: false
|
|
23
22
|
t.datetime "updated_at", null: false
|
|
24
23
|
end
|
|
25
24
|
|
|
26
25
|
create_table "people", force: :cascade do |t|
|
|
27
|
-
t.string
|
|
28
|
-
t.date
|
|
29
|
-
t.decimal
|
|
30
|
-
t.decimal
|
|
31
|
-
t.string
|
|
32
|
-
t.datetime "created_at",
|
|
33
|
-
t.datetime "updated_at",
|
|
26
|
+
t.string "name"
|
|
27
|
+
t.date "born_on"
|
|
28
|
+
t.decimal "height"
|
|
29
|
+
t.decimal "balance_amount"
|
|
30
|
+
t.string "currency"
|
|
31
|
+
t.datetime "created_at", null: false
|
|
32
|
+
t.datetime "updated_at", null: false
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
end
|
|
@@ -5,10 +5,10 @@ class PeopleControllerTest < ActionController::TestCase
|
|
|
5
5
|
get :list
|
|
6
6
|
assert_response :success
|
|
7
7
|
|
|
8
|
-
get :list, format: :csv
|
|
8
|
+
get :list, params: {format: :csv}
|
|
9
9
|
assert_response :success
|
|
10
10
|
|
|
11
|
-
get :list, format: :ods
|
|
11
|
+
get :list, params: {format: :ods}
|
|
12
12
|
assert_response :success
|
|
13
13
|
end
|
|
14
14
|
|
|
@@ -18,19 +18,19 @@ class PeopleControllerTest < ActionController::TestCase
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
test 'parameters' do
|
|
21
|
-
get :list, 'people-id' => 10
|
|
21
|
+
get :list, params: {'people-id' => 10}
|
|
22
22
|
assert_response :success
|
|
23
23
|
|
|
24
|
-
get :list, page: 0
|
|
24
|
+
get :list, params: {page: 0}
|
|
25
25
|
assert_response :success
|
|
26
26
|
|
|
27
|
-
get :list, page: 5, per_page: 25
|
|
27
|
+
get :list, params: {page: 5, per_page: 25}
|
|
28
28
|
assert_response :success
|
|
29
29
|
|
|
30
|
-
get :list, page: 50, per_page: 25
|
|
30
|
+
get :list, params: {page: 50, per_page: 25}
|
|
31
31
|
assert_response :success
|
|
32
32
|
|
|
33
|
-
get :list, page: 500, per_page: 25
|
|
33
|
+
get :list, params: {page: 500, per_page: 25}
|
|
34
34
|
assert_response :success
|
|
35
35
|
end
|
|
36
36
|
end
|
data/test/test_helper.rb
CHANGED
|
@@ -23,6 +23,22 @@ ActionMailer::Base.delivery_method = :test
|
|
|
23
23
|
ActionMailer::Base.perform_deliveries = true
|
|
24
24
|
ActionMailer::Base.default_url_options[:host] = 'test.com'
|
|
25
25
|
|
|
26
|
+
# Patch from https://github.com/rails/rails/issues/34790#issuecomment-450502805
|
|
27
|
+
if RUBY_VERSION >= '2.6.0'
|
|
28
|
+
if Rails.version < '5'
|
|
29
|
+
class ActionController::TestResponse < ActionDispatch::TestResponse
|
|
30
|
+
def recycle!
|
|
31
|
+
# hack to avoid MonitorMixin double-initialize error:
|
|
32
|
+
@mon_mutex_owner_object_id = nil
|
|
33
|
+
@mon_mutex = nil
|
|
34
|
+
initialize
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
puts "Monkeypatch for ActionController::TestResponse no longer needed"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
26
42
|
module ActionView
|
|
27
43
|
class Base
|
|
28
44
|
module Nomen
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active_list
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 7.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brice Texier
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
version: '3.2'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version:
|
|
22
|
+
version: '6'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +29,7 @@ dependencies:
|
|
|
29
29
|
version: '3.2'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: '6'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: arel
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -87,19 +87,33 @@ dependencies:
|
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
88
|
version: '0'
|
|
89
89
|
- !ruby/object:Gem::Dependency
|
|
90
|
-
name:
|
|
90
|
+
name: rodf
|
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
|
93
93
|
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '0'
|
|
96
|
-
type: :
|
|
96
|
+
type: :runtime
|
|
97
97
|
prerelease: false
|
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
|
100
100
|
- - ">="
|
|
101
101
|
- !ruby/object:Gem::Version
|
|
102
102
|
version: '0'
|
|
103
|
+
- !ruby/object:Gem::Dependency
|
|
104
|
+
name: sqlite3
|
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: 1.3.6
|
|
110
|
+
type: :development
|
|
111
|
+
prerelease: false
|
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: 1.3.6
|
|
103
117
|
description: Generates action methods to provide clean tables.
|
|
104
118
|
email: burisu@oneiros.fr
|
|
105
119
|
executables: []
|
|
@@ -208,11 +222,11 @@ files:
|
|
|
208
222
|
- test/people_controller_test.rb
|
|
209
223
|
- test/table_test.rb
|
|
210
224
|
- test/test_helper.rb
|
|
211
|
-
homepage: http://
|
|
225
|
+
homepage: http://gitlab.com/ekylibre/active_list
|
|
212
226
|
licenses:
|
|
213
227
|
- MIT
|
|
214
228
|
metadata: {}
|
|
215
|
-
post_install_message:
|
|
229
|
+
post_install_message:
|
|
216
230
|
rdoc_options: []
|
|
217
231
|
require_paths:
|
|
218
232
|
- lib
|
|
@@ -227,9 +241,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
227
241
|
- !ruby/object:Gem::Version
|
|
228
242
|
version: '0'
|
|
229
243
|
requirements: []
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
signing_key:
|
|
244
|
+
rubygems_version: 3.0.3
|
|
245
|
+
signing_key:
|
|
233
246
|
specification_version: 4
|
|
234
247
|
summary: Simple interactive tables for Rails app
|
|
235
248
|
test_files:
|