active_list 6.9.3 → 7.2.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/csv_exporter.rb +1 -1
- data/lib/active_list/exporters/excel_csv_exporter.rb +1 -1
- data/lib/active_list/exporters/open_document_spreadsheet_exporter.rb +1 -1
- data/lib/active_list/generator.rb +4 -3
- data/lib/active_list/generator/finder.rb +31 -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 +18 -1
- metadata +15 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 884ba63410b0ba502c551bdbf9035360ad2ddefefc959de5d0b3809274e57b60
|
4
|
+
data.tar.gz: 38f2ddcea9c3beb17cc6c4527152f1dba440869e4830d73d8f2c46db0b7c5f7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfa9c5a61880233f0b49f883cfe340a6b63d197a2369fd6a26a079ff87f059fea98ed8ee9f4bc853a97dd6b20112de497923ab62995f642907eb3dfabfcaa877
|
7
|
+
data.tar.gz: e3bf5e8a58a7ecdc81924f71476a433c03fb52b313ff304ebc8755ab13a39b7d2ea60194c669368d1139fbe37321fadbb38c854932fc46fce04d025c1e55e9e1
|
@@ -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
|
@@ -7,7 +7,7 @@ module ActiveList
|
|
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}"
|
@@ -70,7 +70,7 @@ module ActiveList
|
|
70
70
|
code = "# encoding: utf-8\n"
|
71
71
|
code << "def #{view_method_name}(options={}, &block)\n"
|
72
72
|
code << session_initialization_code.dig
|
73
|
-
code <<
|
73
|
+
code << "#{renderer.build_table_code}(options).dig\n"
|
74
74
|
code << "end\n"
|
75
75
|
# code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
|
76
76
|
unless ::Rails.env.production?
|
@@ -83,7 +83,8 @@ module ActiveList
|
|
83
83
|
|
84
84
|
def session_initialization_code
|
85
85
|
code = "options = {} unless options.is_a? Hash\n"
|
86
|
-
|
86
|
+
# For Rails 5
|
87
|
+
code << "options.update(params.to_unsafe_h)\n"
|
87
88
|
if defined?(User) && User.instance_methods.include?(:preference)
|
88
89
|
code << "#{var_name(:params)} = YAML::load(current_user.preference('list.#{view_method_name}', YAML::dump({})).value).symbolize_keys\n"
|
89
90
|
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
|
@@ -111,15 +118,33 @@ module ActiveList
|
|
111
118
|
code
|
112
119
|
end
|
113
120
|
|
121
|
+
def from_code
|
122
|
+
return nil unless @table.options[:from]
|
123
|
+
from = @table.options[:from]
|
124
|
+
code = ''
|
125
|
+
code << '(' + from.gsub(/\s*\n\s*/, ';') + ')'
|
126
|
+
code
|
127
|
+
end
|
128
|
+
|
114
129
|
def select_code
|
115
130
|
return nil unless @table.options[:distinct] || @table.options[:select]
|
116
131
|
code = ''
|
117
132
|
code << 'DISTINCT ' if @table.options[:distinct]
|
118
|
-
code << "#{@table.model.table_name}.*"
|
119
133
|
if @table.options[:select]
|
120
|
-
code << @table.options[:select].collect { |k, v| ", #{k[0].to_s + '.' + k[1].to_s} AS #{v}" }.join
|
134
|
+
# code << @table.options[:select].collect { |k, v| ", #{k[0].to_s + '.' + k[1].to_s} AS #{v}" }.join
|
135
|
+
code << @table.options[:select].collect do |k, v|
|
136
|
+
c = if k.is_a? Array
|
137
|
+
k[0].to_s + '.' + k[1].to_s
|
138
|
+
else
|
139
|
+
k
|
140
|
+
end
|
141
|
+
c += " AS #{v}" unless v.blank?
|
142
|
+
c
|
143
|
+
end.join(', ')
|
144
|
+
else
|
145
|
+
code << "#{@table.model.table_name}.*"
|
121
146
|
end
|
122
|
-
("'
|
147
|
+
('"' + code + '"').c
|
123
148
|
end
|
124
149
|
|
125
150
|
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
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
require 'bundler/setup'
|
2
3
|
require 'pathname'
|
3
4
|
|
@@ -8,7 +9,7 @@ require 'active_list'
|
|
8
9
|
dummy_path = Pathname.new(__FILE__).dirname.join('dummy')
|
9
10
|
|
10
11
|
ENV['BUNDLE_GEMFILE'] = ''
|
11
|
-
Kernel.system("cd #{dummy_path} && bundle install && bundle exec rake db:drop db:create db:migrate db:seed RAILS_ENV=test")
|
12
|
+
# Kernel.system("cd #{dummy_path} && bundle install && bundle exec rake db:drop db:create db:migrate db:seed RAILS_ENV=test")
|
12
13
|
|
13
14
|
# CURRENT FILE :: test/test_helper.rb
|
14
15
|
# Configure Rails Environment
|
@@ -22,6 +23,22 @@ ActionMailer::Base.delivery_method = :test
|
|
22
23
|
ActionMailer::Base.perform_deliveries = true
|
23
24
|
ActionMailer::Base.default_url_options[:host] = 'test.com'
|
24
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
|
+
|
25
42
|
module ActionView
|
26
43
|
class Base
|
27
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.2.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-08 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
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ">="
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.0.
|
53
|
+
version: 0.0.1
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.0.
|
60
|
+
version: 0.0.1
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rubyzip
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,16 +90,16 @@ dependencies:
|
|
90
90
|
name: sqlite3
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
95
|
+
version: 1.3.6
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: 1.3.6
|
103
103
|
description: Generates action methods to provide clean tables.
|
104
104
|
email: burisu@oneiros.fr
|
105
105
|
executables: []
|
@@ -208,11 +208,11 @@ files:
|
|
208
208
|
- test/people_controller_test.rb
|
209
209
|
- test/table_test.rb
|
210
210
|
- test/test_helper.rb
|
211
|
-
homepage: http://
|
211
|
+
homepage: http://gitlab.com/ekylibre/active_list
|
212
212
|
licenses:
|
213
213
|
- MIT
|
214
214
|
metadata: {}
|
215
|
-
post_install_message:
|
215
|
+
post_install_message:
|
216
216
|
rdoc_options: []
|
217
217
|
require_paths:
|
218
218
|
- lib
|
@@ -227,9 +227,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
227
|
- !ruby/object:Gem::Version
|
228
228
|
version: '0'
|
229
229
|
requirements: []
|
230
|
-
|
231
|
-
|
232
|
-
signing_key:
|
230
|
+
rubygems_version: 3.0.3
|
231
|
+
signing_key:
|
233
232
|
specification_version: 4
|
234
233
|
summary: Simple interactive tables for Rails app
|
235
234
|
test_files:
|