simple_drilldown 0.6.7 → 0.7.3

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
  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.