simple_drilldown 0.6.7 → 0.7.3

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
2
  SHA256:
3
- metadata.gz: 20d7b53c9e1fdf228a84a025903f46d614625db9fdd66080576969700136f3a6
4
- data.tar.gz: 75bdf58b4bc191390cdf9aa358a0f9e018c5bc20be0c6f0db8b686deff584a06
3
+ metadata.gz: d998f2cd5f57af22c3c8831275dad5d173180d99000f2770e02db5accf6183ab
4
+ data.tar.gz: c1dab92e5b931b7c2396ad59ffabd97e1b61c8b28bd58a30e5409216488a5dd8
5
5
  SHA512:
6
- metadata.gz: d6a3da501e77e3d0e8c4fdff93372014e7c0761e2971e750ea8de2eea9208174740467a16f55558dc8be69446dce84a1709547664e759d796787620fa2032a58
7
- data.tar.gz: bef5d70dc50b1b68396464410844c05c40698298339476a43c825f09899f9a0d01d0e4283207a30f3b1858415d2bd2509fcc6aad88f61484c10fec7a13244ea6
6
+ metadata.gz: 734f1d871a340e5b6f7c44e28eadc13f91e60b7492bead90f4b6681e0ec1f76db237042856350795d43ac3d0ed2b099dfd74ada3f3c5ba801019a57cd5bde217
7
+ data.tar.gz: 71fe4b0435b2ca9230f4baaea43535522ef48389f37fe1c03b895769de8bf045ba95be62eb39421a9cc7db81039fa94dd7a882f0a21e5fdf33e9ddd251fabb4a
@@ -3,5 +3,8 @@
3
3
  xml << render(partial: '/drilldown/excel_row_header')
4
4
 
5
5
  result[:records].each do |t|
6
- xml << render(partial: '/drilldown/excel_row', locals: { transaction: t, previous_transaction: nil, errors: [], error_row: false, meter1_errors: false })
6
+ xml << render(
7
+ partial: '/drilldown/excel_row',
8
+ locals: { transaction: t, previous_transaction: nil, errors: [], error_row: false, meter1_errors: false }
9
+ )
7
10
  end
@@ -6,7 +6,12 @@ xml.Row do
6
6
 
7
7
  @search.fields.each_with_index do |field, i|
8
8
  if field == 'time'
9
- value = (transaction.respond_to?(:completed_at) ? transaction.completed_at : transaction.created_at).localtime.strftime('%Y-%m-%d %H:%M')
9
+ value = ((
10
+ if transaction.respond_to?(:completed_at)
11
+ transaction.completed_at
12
+ else
13
+ transaction.created_at
14
+ end)).localtime.strftime('%Y-%m-%d %H:%M')
10
15
  else
11
16
  value = if @transaction_fields_map[field.to_sym][:attr_method]
12
17
  @transaction_fields_map[field.to_sym][:attr_method].call(transaction)
@@ -46,8 +46,7 @@ xml.Styles do
46
46
  xml.Interior 'ss:Color' => '#dedede', 'ss:Pattern' => 'Solid'
47
47
  xml.NumberFormat 'ss:Format' => "\#,\#\#0"
48
48
  end
49
- xml.Style 'ss:ID' => 'Outer' do
50
- end
49
+ xml.Style 'ss:ID' => 'Outer'
51
50
  xml.Style 'ss:ID' => 'ShortDate' do
52
51
  xml.NumberFormat 'ss:Format' => 'Short Date'
53
52
  end
@@ -9,7 +9,11 @@ xml.Row do
9
9
  end
10
10
  end
11
11
  if dimension > 0
12
- xml.Cell('ss:StyleID' => 'Outer', 'ss:Index' => dimension.to_s) { xml.Data value_label(dimension - 1, result[:value]), 'ss:Type' => 'String' }
12
+ xml.Cell('ss:StyleID' => 'Outer',
13
+ 'ss:Index' => dimension.to_s) do
14
+ xml.Data value_label(dimension - 1, result[:value]),
15
+ 'ss:Type' => 'String'
16
+ end
13
17
  end
14
18
 
15
19
  xml.Cell('ss:StyleID' => 'Outer') { xml.Data result[:count].inspect, 'ss:Type' => 'Number' }
@@ -4,8 +4,12 @@ xml.chart(xAxisName: (@dimensions[0][:pretty_name] || 'Elections').gsub("'", '')
4
4
  showValues: '1', caption: caption, subcaption: subcaption,
5
5
  yAxisName: "Election #{t(@search.select_value.downcase)}", numberSuffix: '') do
6
6
  @result[:rows].each do |res|
7
- xml.set(name: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(res[:value]) : res[:value],
7
+ xml.set name: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(res[:value]) : res[:value],
8
8
  value: res[@search.select_value.downcase.to_sym],
9
- link: @dimensions[0][:url_param_name] ? CGI.escape(url_for(@search.drill_down(@dimensions, res[:value]).url_options)) : '')
9
+ link: if @dimensions[0][:url_param_name]
10
+ CGI.escape(url_for(@search.drill_down(@dimensions, res[:value]).url_options))
11
+ else
12
+ ''
13
+ end
10
14
  end
11
15
  end
@@ -1,23 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- xml.chart xAxisName: (@dimensions[0][:pretty_name] || 'Elections').gsub("'", ''), palette: '2',
4
- caption: caption, subcaption: subcaption,
5
- showNames: '1', showValues: @result[:rows].size > 15 || @result[:rows][0] && @result[:rows][0][:rows].size > 4 ? 0 : 1, decimals: '0',
6
- numberPrefix: '', clustered: '0', exeTime: '1.5', showPlotBorder: '0', zGapPlot: '30',
7
- zDepth: '90', divLineEffect: 'emboss', startAngX: '10', endAngX: '18', startAngY: '-10',
8
- numberSuffix: '', zAxisName: 'Z Axis', yAxisName: "Transaction #{t(@search.select_value.downcase)}", endAngY: '-40' do
3
+ xml.chart(
4
+ xAxisName: (@dimensions[0][:pretty_name] || 'Elections').gsub("'", ''), palette: '2',
5
+ caption: caption, subcaption: subcaption,
6
+ showNames: '1',
7
+ showValues: @result[:rows].size > 15 || @result[:rows][0] && @result[:rows][0][:rows].size > 4 ? 0 : 1,
8
+ decimals: '0',
9
+ numberPrefix: '', clustered: '0', exeTime: '1.5', showPlotBorder: '0', zGapPlot: '30',
10
+ zDepth: '90', divLineEffect: 'emboss', startAngX: '10', endAngX: '18', startAngY: '-10',
11
+ numberSuffix: '', zAxisName: 'Z Axis',
12
+ yAxisName: "Transaction #{t(@search.select_value.downcase)}", endAngY: '-40'
13
+ ) do
9
14
  unless @result[:rows].empty?
10
15
  xml.categories do
11
16
  @result[:rows].each do |result|
12
- xml.category label: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(result[:value]) : result[:value]
17
+ label_method = @dimensions[0][:label_method]
18
+ xml.category label: label_method ? label_method.call(result[:value]) : result[:value]
13
19
  end
14
20
  end
15
21
 
16
22
  @result[:rows][0][:rows].reverse.each_with_index do |result, i|
17
- xml.dataset seriesName: @dimensions[1][:label_method] ? @dimensions[1][:label_method].call(result[:value]) : result[:value] do
23
+ name = if @dimensions[1][:label_method]
24
+ @dimensions[1][:label_method].call(result[:value])
25
+ else
26
+ result[:value]
27
+ end
28
+ xml.dataset seriesName: name do
18
29
  @result[:rows].each do |res|
19
30
  value = res[:rows].reverse[i][:value]
20
- xml.set(label: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(res[:value]) : "#{res[:value]}, #{value}",
31
+ label_method = @dimensions[0][:label_method]
32
+ xml.set(label: (label_method ? label_method.call(res[:value]) : "#{res[:value]}, #{value}"),
21
33
  value: res[:rows].reverse[i][@search.select_value.downcase.to_sym],
22
34
  link: CGI.escape(url_for(@search.drill_down(@dimensions, res[:value], value).url_options)))
23
35
  end
@@ -1,25 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- xml.chart xAxisName: (@dimensions[0][:pretty_name] || 'Elections').gsub("'", ''), palette: '2',
4
- caption: caption, subcaption: subcaption,
5
- showNames: '1', showValues: @result[:rows].size > 15 || @result[:rows][0] && @result[:rows][0][:rows].size > 4 ? 0 : 1, decimals: '0',
6
- numberPrefix: '', clustered: '0', exeTime: '1.5', showPlotBorder: '0', zGapPlot: '30',
7
- zDepth: '90', divLineEffect: 'emboss', startAngX: '10', endAngX: '18', startAngY: '-10',
8
- numberSuffix: '', zAxisName: 'Z Axis', yAxisName: "Transaction #{t(@search.select_value.downcase)}", endAngY: '-40' do
3
+ xml.chart(
4
+ xAxisName: (@dimensions[0][:pretty_name] || 'Elections').gsub("'", ''), palette: '2',
5
+ caption: caption, subcaption: subcaption,
6
+ showNames: '1',
7
+ showValues:
8
+ @result[:rows].size > 15 || @result[:rows][0] && @result[:rows][0][:rows].size > 4 ? 0 : 1,
9
+ decimals: '0',
10
+ numberPrefix: '', clustered: '0', exeTime: '1.5', showPlotBorder: '0', zGapPlot: '30',
11
+ zDepth: '90', divLineEffect: 'emboss', startAngX: '10', endAngX: '18', startAngY: '-10',
12
+ numberSuffix: '', zAxisName: 'Z Axis',
13
+ yAxisName: "Transaction #{t(@search.select_value.downcase)}", endAngY: '-40'
14
+ ) do
9
15
  unless @result[:rows].empty?
10
16
  xml.categories do
11
17
  @result[:rows].each do |result|
12
- xml.category label: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(result[:value]) : result[:value]
18
+ xml.category label: if @dimensions[0][:label_method]
19
+ @dimensions[0][:label_method].call(result[:value])
20
+ else
21
+ result[:value]
22
+ end
13
23
  end
14
24
  end
15
25
 
16
26
  @result[:rows][0][:rows].reverse.each_with_index do |result, i|
17
- xml.dataset seriesName: @dimensions[1][:label_method] ? @dimensions[1][:label_method].call(result[:value]) : result[:value] do
27
+ series_name =
28
+ if @dimensions[1][:label_method]
29
+ @dimensions[1][:label_method].call(result[:value])
30
+ else
31
+ result[:value]
32
+ end
33
+ xml.dataset seriesName: series_name do
18
34
  @result[:rows].each do |res|
19
35
  value = res[:rows].reverse[i][:value]
20
- xml.set(label: @dimensions[0][:label_method] ? @dimensions[0][:label_method].call(res[:value]) : "#{res[:value]}, #{value}",
21
- value: res[:rows].reverse[i][@search.select_value.downcase.to_sym],
22
- link: CGI.escape(url_for(@search.drill_down(@dimensions, res[:value], value).url_options)))
36
+ xml.set(
37
+ label:
38
+ if @dimensions[0][:label_method]
39
+ @dimensions[0][:label_method].call(res[:value])
40
+ else
41
+ "#{res[:value]}, #{value}"
42
+ end,
43
+ value: res[:rows].reverse[i][@search.select_value.downcase.to_sym],
44
+ link: CGI.escape(url_for(@search.drill_down(@dimensions, res[:value], value).url_options))
45
+ )
23
46
  end
24
47
  end
25
48
  end
@@ -15,12 +15,14 @@ xml.Workbook(
15
15
  xml.Worksheet 'ss:Name' => 'Transaction Summary' do
16
16
  xml.Table do
17
17
  xml.Row 'ss:Height' => '18.75' do
18
- xml.Cell 'ss:MergeAcross' => @search.list ? @search.fields.size - 1 : @dimensions.size + 2, 'ss:StyleID' => 'MainTitle' do
18
+ xml.Cell 'ss:MergeAcross' => @search.list ? @search.fields.size - 1 : @dimensions.size + 2,
19
+ 'ss:StyleID' => 'MainTitle' do
19
20
  xml.Data caption, 'ss:Type' => 'String'
20
21
  end
21
22
  end
22
23
  xml.Row 'ss:Height' => '15.75' do
23
- xml.Cell 'ss:MergeAcross' => @search.list ? @search.fields.size - 1 : @dimensions.size + 2, 'ss:StyleID' => 'SubTitle' do
24
+ xml.Cell 'ss:MergeAcross' => @search.list ? @search.fields.size - 1 : @dimensions.size + 2,
25
+ 'ss:StyleID' => 'SubTitle' do
24
26
  xml.Data subcaption, 'ss:Type' => 'String'
25
27
  end
26
28
  end
@@ -10,7 +10,7 @@ xml.Workbook(
10
10
  'xmlns:ss' => 'urn:schemas-microsoft-com:office:spreadsheet',
11
11
  'xmlns:html' => 'http://www.w3.org/TR/REC-html40'
12
12
  ) do
13
- xml << render(partial: '/layouts/excel_styles')
13
+ xml << render(partial: '/drilldown/excel_styles')
14
14
 
15
15
  xml.Worksheet 'ss:Name' => 'Drilldown' do
16
16
  xml.Table do
@@ -26,17 +26,17 @@ xml.Workbook(
26
26
  end
27
27
 
28
28
  xml.Row 'ss:StyleID' => 'Heading' do
29
- @transaction_fields.each do |field|
29
+ @search.fields.each do |field|
30
30
  if field == 'time'
31
31
  xml.Cell do
32
- xml.Data (l :short_date).to_s, 'ss:Type' => 'String'
32
+ xml.Data (t :short_date).to_s, 'ss:Type' => 'String'
33
33
  end
34
34
  xml.Cell do
35
- xml.Data (l :time).to_s, 'ss:Type' => 'String'
35
+ xml.Data (t :time).to_s, 'ss:Type' => 'String'
36
36
  end
37
37
  else
38
38
  xml.Cell do
39
- xml.Data (l field).to_s, 'ss:Type' => 'String'
39
+ xml.Data (t field).to_s, 'ss:Type' => 'String'
40
40
  end
41
41
  end
42
42
  end
@@ -44,7 +44,7 @@ xml.Workbook(
44
44
 
45
45
  @records.each do |transaction|
46
46
  xml.Row do
47
- @transaction_fields.each do |field|
47
+ @search.fields.each do |field|
48
48
  field_map = controller.c_fields[field.to_sym]
49
49
  if field == 'time'
50
50
  xml.Cell 'ss:StyleID' => 'DateOnlyFormat' do
@@ -54,7 +54,8 @@ xml.Workbook(
54
54
  xml.Data transaction.completed_at.gmtime.xmlschema, 'ss:Type' => 'DateTime'
55
55
  end
56
56
  else
57
- value = field_map[:attr_method] ? field_map[:attr_method].call(transaction) : transaction.send(field)
57
+ attr_method = field_map[:attr_method]
58
+ value = attr_method ? attr_method.call(transaction) : transaction.send(field)
58
59
  xml.Cell field_map[:excel_style] ? { 'ss:StyleID' => field_map[:excel_style] } : {} do
59
60
  xml.Data value, 'ss:Type' => field_map[:excel_type] || 'String'
60
61
  end
@@ -1,6 +1,6 @@
1
- <h1><%=caption%></h2>
2
- <h2><%=subcaption %></h3>
1
+ <h1><%= caption %></h1>
2
+ <h2><%= subcaption %></h2>
3
3
  <br/>
4
4
  <div style="width: 98%; padding: 5px;">
5
- <%=render :partial => '/drilldown/summary_table' %>
5
+ <%= render '/drilldown/summary_table' %>
6
6
  </div>
@@ -1,12 +1,15 @@
1
1
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
3
 
4
4
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
- <%= render 'layouts/headers' %>
6
- <%= stylesheet_link_tag 'drilldown' %>
5
+ <%= stylesheet_link_tag 'application' %>
7
6
  <body>
8
7
  <style type="text/css">
9
- @media print {#print_link {display: none}}
8
+ @media print {
9
+ #print_link {
10
+ display: none
11
+ }
12
+ }
10
13
  </style>
11
14
  <div class="container">
12
15
  <div id="print_link" class="pull-right">
data/config/routes.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  SimpleDrilldown::Engine.routes.draw do
4
+ # No routes, yet.
4
5
  end
@@ -6,6 +6,6 @@ class DrilldownControllerGenerator < Rails::Generators::NamedBase
6
6
  def copy_drilldown_controller_file
7
7
  template 'drilldown_controller.rb.erb', "app/controllers/#{file_name}_drilldown_controller.rb"
8
8
  template 'drilldown_controller_test.rb.erb', "test/controllers/#{file_name}_drilldown_controller_test.rb"
9
- route "draw_drilldown :#{singular_name}_drilldown"
9
+ route "draw_drilldown :#{singular_name}"
10
10
  end
11
11
  end
@@ -33,8 +33,12 @@ module SimpleDrilldown
33
33
  begin
34
34
  base.c_target_class = base.name.chomp('Controller').constantize
35
35
  rescue NameError
36
+ # No default target class found
36
37
  end
37
38
  end
39
+ return unless base.c_target_class.try :paranoid?
40
+
41
+ base.c_base_condition = "#{base.c_target_class.table_name}.deleted_at IS NULL"
38
42
  end
39
43
 
40
44
  def base_condition(base_condition)
@@ -101,7 +105,9 @@ module SimpleDrilldown
101
105
  raise "Unexpected options: #{options.inspect}" if options.present?
102
106
 
103
107
  queries.each do |query_opts|
104
- raise "Unknown options: #{query_opts.keys.inspect}" unless (query_opts.keys - %i[select includes where]).empty?
108
+ unless (query_opts.keys - %i[select includes where]).empty?
109
+ raise "Unknown options: #{query_opts.keys.inspect}"
110
+ end
105
111
  end
106
112
 
107
113
  c_dimension_defs[name.to_s] = {
@@ -125,7 +131,8 @@ module SimpleDrilldown
125
131
  pretty_name: I18n.t(name, default: :"activerecord.models.#{name}"),
126
132
  queries: queries,
127
133
  reverse: reverse,
128
- select_expression: queries.size > 1 ? "COALESCE(#{queries.map { |q| q[:select] }.join(',')})" : queries[0][:select],
134
+ select_expression:
135
+ queries.size == 1 ? queries[0][:select] : "COALESCE(#{queries.map { |q| q[:select] }.join(',')})",
129
136
  row_class: row_class,
130
137
  url_param_name: name.to_s
131
138
  }
@@ -182,7 +189,7 @@ module SimpleDrilldown
182
189
  dimension_def = c_dimension_defs[field]
183
190
  raise "Unknown filter field: #{field.inspect}" if dimension_def.nil?
184
191
 
185
- values = [*values]
192
+ values = Array(values)
186
193
  if dimension_def[:interval]
187
194
  values *= 2 if values.size == 1
188
195
  raise "Need 2 values for interval filter: #{values.inspect}" if values.size != 2
@@ -237,9 +244,9 @@ module SimpleDrilldown
237
244
  when Hash
238
245
  sql = +''
239
246
  include.each do |parent, child|
240
- sql << ' ' + make_join(joins, model, parent)
247
+ sql << " #{make_join(joins, model, parent)}"
241
248
  ass = model.to_s.camelize.constantize.reflect_on_association parent
242
- sql << ' ' + make_join(joins, parent, child, ass.class_name.constantize)
249
+ sql << " #{make_join(joins, parent, child, ass.class_name.constantize)}"
243
250
  end
244
251
  sql
245
252
  when Symbol
@@ -373,8 +380,7 @@ module SimpleDrilldown
373
380
  selected = @search.filter[dimension_name] || []
374
381
  raise "Unknown dimension #{dimension_name.inspect}: #{c_dimension_defs.keys.inspect}" unless dimension
375
382
 
376
- choices = [[t(:all), nil]] +
377
- (dimension[:legal_values]&.call(@search)&.map { |o| o.is_a?(Array) ? o[0..1].map(&:to_s) : o.to_s } || [])
383
+ choices = [[t(:all), nil]] + (legal_values_for_dimension(dimension) || [])
378
384
  choices_html = choices.map do |c|
379
385
  %(<option value="#{c[1]}"#{' SELECTED' if selected.include?(c[1])}>#{c[0]}</option>)
380
386
  end.join("\n")
@@ -383,36 +389,37 @@ module SimpleDrilldown
383
389
 
384
390
  def html_export
385
391
  index(false)
386
- render template: '/drilldown/html_export', layout: 'print'
392
+ render template: '/drilldown/html_export', layout: '../drilldown/print'
387
393
  end
388
394
 
389
395
  def excel_export
390
396
  index(false)
391
- headers['Content-Type'] = 'application/vnd.ms-excel'
392
- headers['Content-Disposition'] = 'attachment; filename="drilldown.xml"'
393
- headers['Cache-Control'] = ''
394
- render template: '/drilldown/excel_export', layout: false
397
+ set_excel_headers
398
+ if params.dig(:search, :list) == '1'
399
+ @records = get_records(@result)
400
+ render template: '/drilldown/excel_export_records', layout: false
401
+ else
402
+ render template: '/drilldown/excel_export', layout: false
403
+ end
395
404
  end
396
405
 
397
406
  def excel_export_records
407
+ params[:search] ||= {}
398
408
  params[:search][:list] = '1'
399
- index(false)
400
- @records = get_records(@result)
401
- headers['Content-Type'] = 'application/vnd.ms-excel'
402
- headers['Content-Disposition'] = 'attachment; filename="drilldown.xml"'
403
- render template: '/drilldown/excel_export_records', layout: false
409
+ excel_export
404
410
  end
405
411
 
406
- def xml_export
407
- params[:search][:list] = '1'
408
- index(false)
409
- @records = get_records(@result)
410
- headers['Content-Type'] = 'text/xml'
411
- headers['Content-Disposition'] = 'attachment; filename="drilldown.xml"'
412
- render template: '/drilldown/xml_export', layout: false
412
+ private
413
+
414
+ def set_excel_headers
415
+ headers['Content-Type'] = 'application/vnd.ms-excel'
416
+ headers['Content-Disposition'] = %{attachment; filename="#{c_target_class.table_name}.xml"}
417
+ headers['Cache-Control'] = ''
413
418
  end
414
419
 
415
- private
420
+ def legal_values_for_dimension(dimension)
421
+ dimension[:legal_values]&.call(@search)&.map { |o| o.is_a?(Array) ? o[0..1].map(&:to_s) : o.to_s }
422
+ end
416
423
 
417
424
  def new_search_object
418
425
  SimpleDrilldown::Search.new(params[:search]&.to_unsafe_h, c_default_fields, c_default_select_value)
@@ -495,7 +502,8 @@ module SimpleDrilldown
495
502
 
496
503
  result_rows = []
497
504
  loop do
498
- sub_result = result_from_rows(rows, row_index, dimension + 1, values + [rows[row_index]["value#{dimension + 1}"]])
505
+ sub_result = result_from_rows(rows, row_index, dimension + 1,
506
+ values + [rows[row_index]["value#{dimension + 1}"]])
499
507
  break if sub_result.nil?
500
508
 
501
509
  result_rows << sub_result
@@ -517,23 +525,20 @@ module SimpleDrilldown
517
525
  end
518
526
 
519
527
  def populate_list(conditions, includes, result, values)
520
- if result[:rows]
521
- return result[:rows].each { |r| populate_list(conditions, includes, r, values + [r[:value]]) }
522
- end
528
+ return result[:rows].each { |r| populate_list(conditions, includes, r, values + [r[:value]]) } if result[:rows]
529
+
523
530
  list_includes = merge_includes(includes, c_list_includes)
524
531
  @search.fields.each do |field|
525
532
  field_def = c_fields[field.to_sym]
526
533
  raise "Field definition missing for: #{field.inspect}" unless field_def
527
534
 
528
535
  field_includes = field_def[:include]
529
- if field_includes
530
- list_includes = merge_includes(list_includes , field_includes)
531
- end
536
+ list_includes = merge_includes(list_includes, field_includes) if field_includes
532
537
  end
533
538
  if @search.list_change_times
534
539
  @history_fields.each do |f|
535
540
  if @search.fields.include? f
536
- list_includes = merge_includes(list_includes, assignment: { order: :"#{f}_changes" } )
541
+ list_includes = merge_includes(list_includes, assignment: { order: :"#{f}_changes" })
537
542
  end
538
543
  end
539
544
  end
@@ -546,12 +551,12 @@ module SimpleDrilldown
546
551
 
547
552
  def merge_includes(*args)
548
553
  hash = hash_includes(*args)
549
- result = hash.dup.map { |k, v|
554
+ result = hash.dup.map do |k, v|
550
555
  if v.blank?
551
556
  hash.delete(k)
552
557
  k
553
558
  end
554
- }.compact
559
+ end.compact
555
560
  result << hash unless hash.blank?
556
561
  case result.size
557
562
  when 0
@@ -567,14 +572,15 @@ module SimpleDrilldown
567
572
  args.inject({}) do |h, inc|
568
573
  case inc
569
574
  when Array
570
- inc.each { |v|
575
+ inc.each do |v|
571
576
  h = hash_includes(h, v)
572
- }
577
+ end
573
578
  when Hash
574
- inc.each { |k, v|
579
+ inc.each do |k, v|
575
580
  h[k] = merge_includes(h[k], v)
576
- }
581
+ end
577
582
  when NilClass, FalseClass
583
+ # Leave as it is
578
584
  when String, Symbol
579
585
  h[inc] ||= []
580
586
  else
@@ -3,6 +3,10 @@
3
3
  module SimpleDrilldown
4
4
  # View helper for SimpleDrilldown
5
5
  module Helper
6
+ # FIXME(uwe): Should not be necessary: https://github.com/rails/rails/issues/41038
7
+ include Rails.application.routes.url_helpers
8
+ # EMXIF
9
+
6
10
  def value_label(dimension_index, value)
7
11
  dimension = @dimensions[dimension_index]
8
12
  return nil if dimension.nil?
@@ -11,9 +15,8 @@ module SimpleDrilldown
11
15
  end
12
16
 
13
17
  def caption
14
- result = @search.title || "#{controller.c_target_class} #{t(@search.select_value.downcase)}" +
15
- (@dimensions && @dimensions.any? ? ' by ' + @dimensions.map { |d| d[:pretty_name] }.join(' and ') : '')
16
- result.gsub('$date', [*@search.filter[:calendar_date]].uniq.join(' - '))
18
+ result = @search.title || caption_txt
19
+ result.gsub('$date', Array(@search.filter[:calendar_date]).uniq.join(' - '))
17
20
  end
18
21
 
19
22
  def subcaption
@@ -21,9 +24,15 @@ module SimpleDrilldown
21
24
  end
22
25
 
23
26
  def summary_row(result, parent_result = nil, dimension = 0, headers = [], new_row = true)
24
- html = render(partial: '/drilldown/summary_row', locals: { result: result, parent_result: parent_result, new_row: new_row, dimension: dimension, headers: headers, with_results: !result[:rows] })
27
+ html = render(partial: '/drilldown/summary_row', locals: {
28
+ result: result, parent_result: parent_result, new_row: new_row, dimension: dimension,
29
+ headers: headers, with_results: !result[:rows]
30
+ })
25
31
  if result[:rows]
26
- sub_headers = headers + [{ value: result[:value], display_row_count: result[:nodes] + result[:row_count] * (@search.list ? 1 : 0) }]
32
+ sub_headers = headers + [{
33
+ value: result[:value],
34
+ display_row_count: result[:nodes] + result[:row_count] * (@search.list ? 1 : 0)
35
+ }]
27
36
  significant_rows = result[:rows].reject { |r| r[:row_count].zero? }
28
37
  significant_rows.each_with_index do |r, i|
29
38
  html << summary_row(r, result, dimension + 1, sub_headers, i.positive?)
@@ -31,7 +40,12 @@ module SimpleDrilldown
31
40
  elsif @search.list
32
41
  html << render(partial: '/drilldown/record_list', locals: { result: result })
33
42
  end
34
- html << render(partial: '/drilldown/summary_total_row', locals: { result: result, parent_result: parent_result, headers: headers.dup, dimension: dimension }) if dimension < @dimensions.size
43
+ if dimension < @dimensions.size
44
+ html << render(partial: '/drilldown/summary_total_row',
45
+ locals: {
46
+ result: result, parent_result: parent_result, headers: headers.dup, dimension: dimension
47
+ })
48
+ end
35
49
 
36
50
  html
37
51
  end
@@ -41,25 +55,42 @@ module SimpleDrilldown
41
55
  if result[:rows]
42
56
  significant_rows = result[:rows].reject { |r| r[:row_count].zero? }
43
57
  significant_rows.each_with_index do |r, i|
44
- sub_headers = if i.zero?
45
- if dimension.zero?
46
- headers
47
- else
48
- headers + [{ value: result[:value], display_row_count: result[:nodes] + result[:row_count] * (@search.list ? 1 : 0) }]
49
- end
50
- else
51
- [] # [{:value => result[:value], :row_count => result[:row_count]}]
52
- end
58
+ sub_headers =
59
+ if i.zero?
60
+ if dimension.zero?
61
+ headers
62
+ else
63
+ headers + [{
64
+ value: result[:value],
65
+ display_row_count: result[:nodes] + result[:row_count] * (@search.list ? 1 : 0)
66
+ }]
67
+ end
68
+ else
69
+ [] # [{:value => result[:value], :row_count => result[:row_count]}]
70
+ end
53
71
  xml << excel_summary_row(r, result, dimension + 1, sub_headers)
54
72
  end
55
73
  else
56
- xml << render(partial: '/drilldown/excel_summary_row', locals: { result: result, parent_result: parent_result, headers: headers.dup, dimension: dimension })
74
+ xml << render(partial: '/drilldown/excel_summary_row',
75
+ locals: { result: result, parent_result: parent_result, headers: headers.dup,
76
+ dimension: dimension })
57
77
 
58
78
  xml << render(partial: '/drilldown/excel_record_list', locals: { result: result }) if @search.list
59
79
  end
60
80
 
61
- xml << render(partial: '/drilldown/excel_summary_total_row', locals: { result: result, headers: headers.dup, dimension: dimension }) if dimension < @dimensions.size
81
+ if dimension < @dimensions.size
82
+ xml << render(partial: '/drilldown/excel_summary_total_row', locals: {
83
+ result: result, headers: headers.dup, dimension: dimension
84
+ })
85
+ end
62
86
  xml
63
87
  end
88
+
89
+ private
90
+
91
+ def caption_txt
92
+ "#{controller.c_target_class} #{t(@search.select_value.downcase)}" +
93
+ (@dimensions && @dimensions.any? ? " by #{@dimensions.map { |d| d[:pretty_name] }.join(' and ')}" : '')
94
+ end
64
95
  end
65
96
  end
@@ -3,12 +3,13 @@
3
3
  module SimpleDrilldown
4
4
  # Routing helper methods
5
5
  module Routing
6
- def draw_drilldown(path, controller = path)
6
+ def draw_drilldown(path, controller = nil)
7
+ path = "#{path}_drilldown" unless /_drilldown$/.match?(path)
8
+ controller ||= path
7
9
  get "#{path}(.:format)" => "#{controller}#index", as: path
8
- scope path do
9
- %i[choices excel_export html_export index].each do |action|
10
- get "#{action}(/:id)(.:format)", controller: controller, action: action
11
- end
10
+ scope path, controller: controller, as: path do
11
+ %i[excel_export excel_export_records html_export].each { |action| get action }
12
+ get 'choices/:dimension_name', action: :choices, as: :choices
12
13
  end
13
14
  end
14
15
  end
@@ -19,17 +19,9 @@ module SimpleDrilldown
19
19
  VOLUME_COMPENSATED = 'VOLUME_COMPENSATED'
20
20
  end
21
21
 
22
- attr_reader :dimensions
23
- attr_reader :display_type
24
- attr_reader :fields
25
- attr_reader :filter
26
- attr_accessor :list
27
- attr_accessor :percent
28
- attr_reader :list_change_times
29
- attr_reader :order_by_value
30
- attr_reader :select_value
31
- attr_reader :title
32
- attr_reader :default_fields
22
+ attr_reader :dimensions, :display_type, :fields, :filter, :list_change_times, :order_by_value,
23
+ :select_value, :title, :default_fields
24
+ attr_accessor :list, :percent
33
25
 
34
26
  def self.validators_on(_attribute)
35
27
  []
@@ -60,7 +52,7 @@ module SimpleDrilldown
60
52
  @dimensions = attributes && attributes[:dimensions] || []
61
53
  @dimensions.delete_if(&:empty?)
62
54
  @filter = attributes && attributes[:filter] ? attributes[:filter] : {}
63
- @filter.keys.dup.each { |k| @filter[k] = [*@filter[k]] }
55
+ @filter.keys.dup.each { |k| @filter[k] = Array(@filter[k]) }
64
56
  @filter.each do |_k, v|
65
57
  v.delete('')
66
58
  v.delete('Select Some Options')
@@ -1,3 +1,3 @@
1
1
  module SimpleDrilldown
2
- VERSION = '0.6.7'
2
+ VERSION = '0.7.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_drilldown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7
4
+ version: 0.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uwe Kubosch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-13 00:00:00.000000000 Z
11
+ date: 2021-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chartkick
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.80'
53
+ version: '1.1'
54
54
  type: :development
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.80'
60
+ version: '1.1'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: sqlite3
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -113,7 +113,7 @@ files:
113
113
  - app/views/drilldown/data_2.builder
114
114
  - app/views/drilldown/data_3.builder
115
115
  - app/views/drilldown/excel_export.builder
116
- - app/views/drilldown/excel_export_transactions.builder
116
+ - app/views/drilldown/excel_export_records.builder
117
117
  - app/views/drilldown/html_export.html.erb
118
118
  - app/views/drilldown/index.html.erb
119
119
  - app/views/drilldown/print.html.erb
@@ -146,14 +146,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
146
  requirements:
147
147
  - - ">="
148
148
  - !ruby/object:Gem::Version
149
- version: '0'
149
+ version: '2.5'
150
150
  required_rubygems_version: !ruby/object:Gem::Requirement
151
151
  requirements:
152
152
  - - ">="
153
153
  - !ruby/object:Gem::Version
154
154
  version: '0'
155
155
  requirements: []
156
- rubygems_version: 3.1.2
156
+ rubygems_version: 3.2.3
157
157
  signing_key:
158
158
  specification_version: 4
159
159
  summary: Simple data warehouse and drilldown.