active_list 6.6.2 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 07c85cc2a20ffb149c1acf358af1b596175b36f7
4
- data.tar.gz: f2581de3877caed78f8ecd7cfb7154948fe958a2
3
+ metadata.gz: 775b3110948e7e0da35e95a8e44f6c0ffe2e01c0
4
+ data.tar.gz: a5d9ae7e758ea41b87666316ddcd35be1510283e
5
5
  SHA512:
6
- metadata.gz: 8e1c2e01f8c3f0a7ce7cfaecc0418928ea83322fc6cdc858505efe3aa367580f88e9fa6b683747f78b50c693873bbc14a32c7bfde92b7922acc50cee22b71a6f
7
- data.tar.gz: 8cbae458b67ae355bd2c79feed69c9bec09c6699f5de16a03a7ca0965c1435f8dce7eec5a6417c398d90fa9823809c7bbaf69e8d244fbb56c56d25f7aa8d8f04
6
+ metadata.gz: bd143bcd93b403eef747ba74b118d5c30f5ffec7beee2625ece0a6272e0a54180f83329790f2fab3c99c9cf0e26cfc76dfdec4977cc4ee5ab60d278c700d0407
7
+ data.tar.gz: 77cd8e43c60e2d63cc95eeb6c681a66bb21193c26184c556e3717e5be642ec6e0dad8a4d7fb00cd1b8f97a677dc460427ab32a0adb8d0a0c05b0f8175e4b5f14
@@ -2,7 +2,7 @@ ActiveList = {}
2
2
 
3
3
  (($, AL) ->
4
4
  "use strict"
5
-
5
+
6
6
  # Main function which reload table with specified data parameters
7
7
  AL.refresh = (list, options) ->
8
8
  table = list.find("table[data-current-page]").first()
@@ -25,16 +25,14 @@ ActiveList = {}
25
25
  list_control = content.find(".list-control")
26
26
  for type in ["actions", "pagination", "settings"]
27
27
  $("*[data-list-ref='#{list_id}'].list-#{type}").replaceWith list_control.find(".list-#{type}")
28
-
29
28
  list.find(".list-data").html(list_data)
30
-
31
- # list.html data
32
29
  selection = list.prop('selection')
33
30
  if selection?
34
- for id in selection
31
+ for id in Object.keys(selection)
35
32
  list.find("input[data-list-selector='#{id}']")
36
33
  .attr('checked', 'checked')
37
34
  .closest('tr').addClass('selected')
35
+ AL.updateResults list
38
36
  AL.checkGlobalButtons list
39
37
  list.trigger('page:change')
40
38
  $(document).trigger('list:page:change')
@@ -42,35 +40,86 @@ ActiveList = {}
42
40
 
43
41
  false
44
42
 
43
+ values_for_computation_of_rows = (list, row, existing_hash) ->
44
+ computes = {}
45
+ computes = existing_hash if existing_hash?
46
+ for cell in row.find('td')
47
+ continue unless AL.computation_for(list, cell)?
48
+ col_number = AL.column_number(list, cell)
49
+ computes[col_number] = [] unless computes[col_number]?
50
+ computes[col_number].push parseFloat(AL.unaltered_value(cell))
51
+ computes
52
+
53
+ AL.column_for = (list, cell) ->
54
+ if typeof(cell) == "string"
55
+ column = cell
56
+ else
57
+ column = $(cell).data('list-column-header')
58
+ list.find("th[data-list-column-cells='#{column}']")
59
+
60
+ AL.computation_for = (list, cell) ->
61
+ AL.column_for(list, cell).data('list-column-computation')
62
+
63
+ AL.column_number = (list, cell) ->
64
+ AL.column_for(list, cell).data('list-column-cells')
65
+
66
+ AL.unaltered_value = (cell) ->
67
+ $(cell).data('list-cell-value')
45
68
 
46
69
  # Select a row of "many" buttons
47
70
  AL.select = (checkbox) ->
48
71
  list = checkbox.closest('*[data-list-source]')
49
72
  row = checkbox.closest('tr')
50
- if list.prop('selection')?
51
- selection = list.prop('selection')
52
- else
53
- selection = []
73
+ selection = if list.prop('selection')? then list.prop('selection') else {}
54
74
  key = checkbox.data('list-selector')
55
- index = selection.indexOf(key)
75
+ present = String(key) in Object.keys(selection)
56
76
  if checkbox.is ":checked"
57
- if index < 0
58
- selection.push(key)
77
+ selection[key] = values_for_computation_of_rows(list, row, selection[key]) unless present
59
78
  row.addClass("selected")
60
79
  else
61
- if index >= 0
62
- selection.splice(index, 1)
80
+ delete selection[key] if present
63
81
  row.removeClass("selected")
64
82
  list.prop('selection', selection)
83
+
84
+ AL.updateResults list
65
85
  AL.checkGlobalButtons list
66
86
 
87
+ AL.updateResults = (list) ->
88
+ results = {}
89
+ selection = if list.prop('selection')? then list.prop('selection') else {}
90
+ for key, columns of selection
91
+ for column, values of columns
92
+ computation = AL.computation_for(list, column)
93
+ unless computation == 'sum' || computation == 'average'
94
+ console.log "Don't know how to handle computation #{computation}. Skipping."
95
+ continue
96
+ results[column] = [] if typeof(results[column]) == "undefined"
97
+ results[column] = results[column].concat values
98
+
99
+ for column, values of results
100
+ float_values = (parseFloat(e) for e in values)
101
+ total = values.reduce (t, s) -> t + s
102
+ total /= values.length if AL.computation_for(list, column) == 'average'
103
+ list.attr("data-list-result-#{column}", total)
104
+ currency_precision = parseInt(AL.column_for(list, column).data('list-column-currency-precision'))
105
+ currency_symbol = AL.column_for(list, column).data('list-column-currency-symbol')
106
+ if currency_precision and currency_symbol
107
+ magnitude = Math.pow(10, currency_precision)
108
+ rounded = Math.round(total * magnitude) / magnitude
109
+ displayable_total = "#{rounded} #{currency_symbol}"
110
+ list.find("#computation-results td[data-list-result-for=\"#{column}\"] #list-computation-result").html(displayable_total)
111
+ for column in list.find("th[data-list-column-computation]")
112
+ col_number = $(column).data('list-column-cells')
113
+ continue unless typeof(results[col_number]) == "undefined" or results[col_number].length == 0
114
+ list.removeAttr("data-list-result-#{col_number}")
115
+ list.find("#computation-results td[data-list-result-for=\"#{col_number}\"] #list-computation-result").html('')
67
116
 
68
117
  # Hide/show needed global buttons
69
- AL.checkGlobalButtons = (list) ->
118
+ AL.checkGlobalButtons = (list) ->
70
119
  selection = list.prop('selection')
71
120
  list_id = list.attr('id')
72
121
  actions = $("*[data-list-ref='#{list_id}']")
73
- if selection.length > 0
122
+ if Object.keys(selection).length > 0
74
123
  actions.find("*[data-list-actioner='none']:visible").hide()
75
124
  actions.find("*[data-list-actioner='none']:visible").hide()
76
125
  actions.find("*[data-list-actioner='many']:hidden").show()
@@ -82,7 +131,7 @@ ActiveList = {}
82
131
  unless button.prop('hrefPattern')?
83
132
  button.prop('hrefPattern', button.attr('href'))
84
133
  pattern = button.prop('hrefPattern')
85
- url = pattern.replace(encodeURIComponent("##IDS##"), selection.join(','), 'g')
134
+ url = pattern.replace(encodeURIComponent("##IDS##"), Object.keys(selection).join(','), 'g')
86
135
  button.attr("href", url)
87
136
 
88
137
  # Move to given page
@@ -107,15 +156,15 @@ ActiveList = {}
107
156
  $(document).on "click", "*[data-list-source] input[data-list-selector]", (event) ->
108
157
  AL.select $(this)
109
158
  true
110
-
159
+
111
160
  # Adds title attribute based on link name
112
161
  $(document).on "hover", "*[data-list-source] tbody tr td.act a", (event) ->
113
162
  element = $(this)
114
163
  title = element.attr("title")
115
164
  element.attr "title", element.html() unless title?
116
- return
165
+ return
166
+
117
167
 
118
-
119
168
  # Change number of item per page
120
169
  $(document).on "click", "*[data-list-ref] *[data-list-change-page-size]", (event) ->
121
170
  sizer = $(this)
@@ -128,7 +177,6 @@ ActiveList = {}
128
177
  per_page: per_page
129
178
  false
130
179
 
131
-
132
180
  # Toggle visibility of a column
133
181
  $(document).on "click", "*[data-list-ref] *[data-list-toggle-column]", (event) ->
134
182
  toggler = $(this)
@@ -136,7 +184,7 @@ ActiveList = {}
136
184
  columnId = toggler.data("list-toggle-column")
137
185
  list = $("##{toggler.closest('*[data-list-ref]').data('list-ref')}")
138
186
  column = list.find("th[data-list-column=\"#{columnId}\"]")
139
-
187
+
140
188
  className = column.data("list-column-cells")
141
189
  className = columnId unless className?
142
190
  search = ".#{className}"
@@ -159,7 +207,6 @@ ActiveList = {}
159
207
  column: columnId
160
208
  false
161
209
 
162
-
163
210
  # Change page of table on link clicks
164
211
  $(document).on "click", "*[data-list-ref] a[data-list-move-to-page]", (event) ->
165
212
  pager = $(this)
@@ -27,6 +27,10 @@ module ActiveList
27
27
  false
28
28
  end
29
29
 
30
+ def computable?
31
+ false
32
+ end
33
+
30
34
  # Unique identifier of the column in the application
31
35
  def unique_id
32
36
  "#{@table.name}-#{@name}"
@@ -1,7 +1,7 @@
1
1
  module ActiveList
2
2
  module Definition
3
3
  class AttributeColumn < DataColumn
4
- attr_reader :column, :label_method, :sort_column
4
+ attr_reader :column, :label_method, :sort_column, :computation_method
5
5
 
6
6
  def initialize(table, name, options = {})
7
7
  super(table, name, options)
@@ -15,6 +15,7 @@ module ActiveList
15
15
  @sort_column = nil
16
16
  end
17
17
  end
18
+ @computation_method = options[:on_select]
18
19
  @column = @table.model.columns_hash[@label_method.to_s]
19
20
  end
20
21
 
@@ -42,6 +43,10 @@ module ActiveList
42
43
  !sort_column.nil?
43
44
  end
44
45
 
46
+ def computable?
47
+ !computation_method.nil?
48
+ end
49
+
45
50
  def enumerize?
46
51
  table.model.send(@label_method).send(:values)
47
52
  return true
@@ -69,7 +69,7 @@ module ActiveList
69
69
  def sortable?
70
70
  return true
71
71
  # not self.action? and
72
- !options[:through] && !@column.nil?
72
+ #!options[:through] && !@column.nil?
73
73
  end
74
74
 
75
75
  # Generate code in order to get the (foreign) record of the column
@@ -55,7 +55,7 @@ module ActiveList
55
55
  end
56
56
 
57
57
  def selectable?
58
- action_columns.select(&:use_many?).any?
58
+ @options[:selectable] || action_columns.select(&:use_many?).any?
59
59
  end
60
60
 
61
61
  # Retrieves all columns in database
@@ -1,6 +1,9 @@
1
1
  ar: &ar
2
2
  list:
3
3
  # columns: "Columns"
4
+ # results:
5
+ # sum: "Total"
6
+ # average: "Moyenne"
4
7
  export:
5
8
  false_value: "زائف"
6
9
  formats:
@@ -1,5 +1,8 @@
1
1
  en: &en
2
2
  list:
3
+ results:
4
+ sum: "Total"
5
+ average: "Average"
3
6
  columns: "Columns"
4
7
  export:
5
8
  false_value: "FALSE"
@@ -1,6 +1,9 @@
1
1
  es: &es
2
2
  list:
3
3
  columns: "Columnas"
4
+ # results:
5
+ # sum: "Total"
6
+ # average: "Moyenne"
4
7
  export:
5
8
  false_value: "FALSO"
6
9
  formats:
@@ -1,6 +1,9 @@
1
1
  fr: &fr
2
2
  list:
3
3
  columns: "Colonnes"
4
+ results:
5
+ sum: "Total"
6
+ average: "Moyenne"
4
7
  export:
5
8
  false_value: "FAUX"
6
9
  formats:
@@ -1,6 +1,9 @@
1
1
  jp: &jp
2
2
  list:
3
3
  columns: "列"
4
+ # results:
5
+ # sum: "Total"
6
+ # average: "Moyenne"
4
7
  export:
5
8
  false_value: "偽"
6
9
  formats:
@@ -70,6 +70,31 @@ module ActiveList
70
70
  # code << " end\n"
71
71
  # end
72
72
  code << " end\n"
73
+
74
+ if table.columns.any?(&:computable?)
75
+ code << " #{var_name(:tbody)} << content_tag(:tr, id: :'computation-results') do\n"
76
+ code << " computation_row = ''\n"
77
+ code << " computation_row << '<td></td>'\n" if table.selectable?
78
+ table.columns.each do |column|
79
+ classes = []
80
+ value = ''
81
+ code << " computation_row << \"<td"
82
+ if column.computable?
83
+ code << " data-list-result-for='#{column.short_id}'"
84
+ value = "<div><span><strong>#{I18n.translate("list.results.#{column.computation_method}")}:</strong></span>"
85
+ value << "<span id='list-computation-result'></span></div>"
86
+ end
87
+ if column.is_a? ActiveList::Definition::DataColumn
88
+ code << "\#\{' class=hidden' if #{var_name(:params)}[:hidden_columns].include?(:#{column.name})\}"
89
+ end
90
+ code << ">"
91
+ code << value
92
+ code << "</td>\"\n"
93
+ end
94
+ code << " computation_row.html_safe\n"
95
+ code << " end\n"
96
+ end
97
+
73
98
  code << "else\n"
74
99
  code << " #{var_name(:tbody)} << '<tr class=\"empty\"><td colspan=\"#{table.columns.size + 1}\">' + ::I18n.translate('list.no_records') + '</td></tr>'\n"
75
100
  code << "end\n"
@@ -108,6 +133,7 @@ module ActiveList
108
133
 
109
134
  # Build whole
110
135
  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"
136
+ # File.open('debug-activelist', 'w') { |file| file.write code }
111
137
  code
112
138
  end
113
139
 
@@ -210,7 +236,10 @@ module ActiveList
210
236
  else
211
237
  value_code = "'&#160;&#8709;&#160;'.html_safe"
212
238
  end
213
- code << "content_tag(:td, :class => \"#{column_classes(column)}\") do\n"
239
+ code << "content_tag(:td, :class => \"#{column_classes(column)}\","
240
+ code << " data: { \"list-column-header\": \"#{column.short_id}\","
241
+ code << " \"list-cell-value\": \"\#{#{column.datum_code(record, children_mode)}}\"" if column.computable?
242
+ code << " } ) do\n"
214
243
  code << value_code.dig
215
244
  code << "end +\n"
216
245
  end
@@ -271,6 +300,11 @@ module ActiveList
271
300
  code << "<th data-list-column=\"#{column.sort_id}\""
272
301
  code << " data-list-column-cells=\"#{column.short_id}\""
273
302
  code << " data-list-column-sort=\"'+(#{var_name(:params)}[:sort] != '#{column.sort_id}' ? 'asc' : #{var_name(:params)}[:dir] == 'asc' ? 'desc' : 'asc')+'\"" if column.sortable?
303
+ code << " data-list-column-computation=\"#{column.computation_method}\"" if column.computable?
304
+ if column.is_a?(ActiveList::Definition::DataColumn) && column.options[:currency]
305
+ code << " data-list-column-currency-symbol=\"' + Nomen::Currencies[#{generator.records_variable_name}.first.currency].symbol + '\""
306
+ code << " data-list-column-currency-precision=\"' + Nomen::Currencies[#{generator.records_variable_name}.first.currency].precision.to_s + '\""
307
+ end
274
308
  code << " class=\"#{column_classes(column, true, true)}\""
275
309
  code << '>'
276
310
  code << "' + h(#{column.header_code}) + '"
@@ -1,3 +1,3 @@
1
1
  module ActiveList
2
- VERSION = '6.6.2'
2
+ VERSION = '6.7.0'
3
3
  end
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: 6.6.2
4
+ version: 6.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brice Texier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-10 00:00:00.000000000 Z
11
+ date: 2016-12-09 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: '5'
22
+ version: 5.1.0
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: '5'
32
+ version: 5.1.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: arel
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -228,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
228
228
  version: '0'
229
229
  requirements: []
230
230
  rubyforge_project:
231
- rubygems_version: 2.5.1
231
+ rubygems_version: 2.4.5.1
232
232
  signing_key:
233
233
  specification_version: 4
234
234
  summary: Simple interactive tables for Rails app