active_list 6.9.4 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8b860bd10a1b420c93a9c97b1b80b98b350928b1
4
- data.tar.gz: abf875e4b6fea99f161ed9cf39507cf6c7d33358
2
+ SHA256:
3
+ metadata.gz: 493c967944f09543ead6e2782c62bbf1379d7db9ce73aaf99a31a30ae7f7ef26
4
+ data.tar.gz: 5b06ebaf0f046687c035febfd6399d86c700ab15540aa8629faf30793889dc29
5
5
  SHA512:
6
- metadata.gz: ec7e678f2f037d0bd2539a541300a11dc6a7a4e2428d98b7bca6a1bb89d2b83f35cdbeecd5758f5e746c40a6f4de164372f3dadd4363e20f4e53bd9c6623d554
7
- data.tar.gz: 7dd686f77a080a88027a2f82792744e0d53f0e96f07a9fdd57e4847dcb0fbb74914ce2584eb2cb4bb4f52fc404061a2b0a0d06772962df798ca6ce0ebbb7a88d
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
 
@@ -78,7 +78,7 @@
78
78
  @include background(transparentize(mix($theme-color, #FFF, 40%), 0.7));
79
79
  }
80
80
 
81
- .list-pagination {
81
+ .list-pagination, .list-footer-pagination {
82
82
  & { text-align: left; }
83
83
  html[dir="rtl"] & { text-align: right; }
84
84
  & > * {
@@ -4,6 +4,7 @@ require 'action_dispatch'
4
4
  require 'rails'
5
5
  require 'code_string'
6
6
  require 'i18n-complements'
7
+ require 'tmpdir'
7
8
 
8
9
  module ActiveList
9
10
  # Build and returns a short UID
@@ -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
- unless @sort_column = options[:sort]
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
- table.model.name
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
- "#{@table.model.table_name}.#{@sort_column}"
85
+ @sort_column
74
86
  end
75
87
  end
76
88
  end
@@ -1,6 +1,10 @@
1
1
  module ActiveList
2
2
  module Definition
3
3
  class EmptyColumn < AbstractColumn
4
+
5
+ def header_code
6
+ "#{name.to_s.strip.inspect}.t(scope: 'labels')".c
7
+ end
4
8
  end
5
9
  end
6
10
  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, "#{self.class.name}#format_data_code is not implemented."
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::CSV
10
+ Mime[:csv]
10
11
  end
11
12
 
12
- def send_data_code
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::XCSV
13
+ Mime[:xcsv]
13
14
  end
14
15
 
15
- def send_data_code
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 'zip'
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::ODS
17
+ Mime[:ods]
23
18
  end
24
19
 
25
- def send_data_code
26
- xml_escape = "to_s.gsub('&', '&amp;').gsub('\\'', '&apos;').gsub('<', '&lt;').gsub('>', '&gt;')"
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 << " zile << ('<?xml version=\"1.0\" encoding=\"UTF-8\"?><office:document-content xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\" xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\" xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\" xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\" xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\" xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\" xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\" xmlns:math=\"http://www.w3.org/1998/Math/MathML\" xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\" xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\" xmlns:ooo=\"http://openoffice.org/2004/office\" xmlns:ooow=\"http://openoffice.org/2004/writer\" xmlns:oooc=\"http://openoffice.org/2004/calc\" xmlns:dom=\"http://www.w3.org/2001/xml-events\" xmlns:xforms=\"http://www.w3.org/2002/xforms\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:field=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:field:1.0\" office:version=\"1.1\"><office:scripts/>')\n"
44
- # Styles
45
- code << " zile << ('<office:automatic-styles>"\
46
- '<style:style style:name="co1" style:family="table-column"><style:table-column-properties fo:break-before="auto" style:use-optimal-column-width="true"/></style:style>'\
47
- '<style:style style:name="header" style:family="table-cell"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/></style:style>'\
48
- '<number:date-style style:name="K4D" number:automatic-order="true"><number:text>' + ::I18n.translate('date.formats.default').gsub(/\%./) { |x| '</number:text>' + DATE_ELEMENTS[x[1..1]] + '<number:text>' } + '</number:text></number:date-style><style:style style:name="ce1" style:family="table-cell" style:data-style-name="K4D"/>'\
49
- "</office:automatic-styles>')\n"
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
- # Tables
52
- code << " zile << ('<office:body><office:spreadsheet><table:table table:name=\"'+#{table.model.name}.model_name.human.#{xml_escape}+'\">')\n"
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).send_data_code.dig(3)
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 << renderer.build_table_code.dig
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
- code << "options.update(params)\n"
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 << "#{var_name(:count)} = #{query_code}.count\n"
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
- ("'" + code + "'").c
205
+ ('"' + code + '"').c
123
206
  end
124
207
 
125
208
  def sanitize_condition(value)
@@ -20,11 +20,12 @@ module ActiveList
20
20
  end
21
21
  end
22
22
 
23
- def urlify(value, record_name)
24
- if value.is_a?(CodeString)
25
- '(' + value.gsub(/RECORD/, record_name) + ')'
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.inspect
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 params['#{table.name}-id'].to_i == #{record}.id\n"
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 params['#{table.name}-id'].to_i == #{record}.id\n"
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=\"' + params[:redirect].to_s + '\" class=\"active-list\">' + #{var_name(:content)} + '</div>').html_safe\n"
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
- value_code = "content_tag(:span, #{lights}, :class => 'lights lights-' + (#{levels.inspect}.include?(#{value_code}.to_s) ? #{value_code}.to_s : 'undefined'))"
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
- column.options[:url][:controller] ||= column.class_name.tableize.to_sym # (self.generator.collection? ? "RECORD.class.name.tableize".c : column.class_name.tableize.to_sym)
193
- # column.options[:url][:controller] ||= "#{value_code}.class.name.tableize".c
194
- url = column.options[:url].collect { |k, v| "#{k}: " + urlify(v, record) }.join(', ')
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 = "'&#160;&#8709;&#160;'.html_safe"
236
270
  end
237
- code << "content_tag(:td, :class => \"#{column_classes(column)}\","
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'))), params.merge(action: :#{generator.controller_method_name}, sort: #{var_name(:params)}[:sort], dir: #{var_name(:params)}[:dir], format: '#{format}')) + '</li>"
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
- conds << [:hidden, "#{var_name(:params)}[:hidden_columns].include?(:#{column.name})".c] if column.is_a? ActiveList::Definition::DataColumn
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
@@ -1,3 +1,3 @@
1
1
  module ActiveList
2
- VERSION = '6.9.4'.freeze
2
+ VERSION = '7.3.0'.freeze
3
3
  end
@@ -1,23 +1,25 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '4.2.10'
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', '~> 4'
15
- gem 'coffee-rails', '~> 4'
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', '>= 1.0.3'
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'
@@ -1,4 +1,4 @@
1
- class CreatePeople < ActiveRecord::Migration
1
+ class CreatePeople < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :people do |t|
4
4
  t.string :name
@@ -1,4 +1,4 @@
1
- class CreateContacts < ActiveRecord::Migration
1
+ class CreateContacts < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  create_table :contacts do |t|
4
4
  t.integer :person_id
@@ -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: 20120510134500) do
13
+ ActiveRecord::Schema.define(version: 2012_05_10_134500) do
15
14
 
16
15
  create_table "contacts", force: :cascade do |t|
17
- t.integer "person_id"
18
- t.text "address"
19
- t.string "phone"
20
- t.string "fax"
21
- t.string "country"
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 "name"
28
- t.date "born_on"
29
- t.decimal "height"
30
- t.decimal "balance_amount"
31
- t.string "currency"
32
- t.datetime "created_at", null: false
33
- t.datetime "updated_at", null: false
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
@@ -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: 6.9.4
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: 2017-12-06 00:00:00.000000000 Z
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: 5.0.0
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: 5.0.0
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: sqlite3
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: :development
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://github.com/ekylibre/active_list
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
- rubyforge_project:
231
- rubygems_version: 2.5.2
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: