reports_kit 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2dcd95571d20aa7e439e9b97a97cefbd87ab3900
4
- data.tar.gz: 5ca4d871580f9d8dba7fa71a8219d6997a1b6472
3
+ metadata.gz: 13094de820c79cec7858078fa4c307a0137c001f
4
+ data.tar.gz: 971b1281d81369b1539aad7c4ac977a72c66558b
5
5
  SHA512:
6
- metadata.gz: 63afd0e91d6953bd43313af32908090c758a8adae00f56a2ce520af5cd934237f549cbf66e6fd32da95642f301b8888017ab3de4c6306a748a78d07189100445
7
- data.tar.gz: d46b89fd02d6183f09ab3de6cb1550718c5f04319cb3dfa673bfc27f9b0fba41290bcf82e5a98a3478954707e778ca40b14aa3fb873810de165f4b43c8754fb6
6
+ metadata.gz: 9c2d64e334083cb58173e9d3ae7daa4453a45c2f6715bf971ea01bc5b1f1b4a0d01bcddf4abc50c7acdaa2d2cedf31bc78ddbe16e1f8e97e363f0200fe53f8e4
7
+ data.tar.gz: f666b9e785d28c22754f8fd6e3fe178f04f3add4599b3b0673240e15d3ea7547a051e952ae683b3a334a6de6d43e24bcb062c86a95c61646e74f916aa9064691
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- reports_kit (0.3.2)
4
+ reports_kit (0.4.0)
5
5
  rails (>= 3)
6
6
  spreadsheet (>= 1.1)
7
7
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- reports_kit (0.3.2)
4
+ reports_kit (0.4.0)
5
5
  rails (>= 3)
6
6
  spreadsheet (>= 1.1)
7
7
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- reports_kit (0.3.2)
4
+ reports_kit (0.4.0)
5
5
  rails (>= 3)
6
6
  spreadsheet (>= 1.1)
7
7
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- reports_kit (0.3.2)
4
+ reports_kit (0.4.0)
5
5
  rails (>= 3)
6
6
  spreadsheet (>= 1.1)
7
7
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- reports_kit (0.3.2)
4
+ reports_kit (0.4.0)
5
5
  rails (>= 3)
6
6
  spreadsheet (>= 1.1)
7
7
 
@@ -31,6 +31,7 @@ require 'reports_kit/reports/data/format_table'
31
31
  require 'reports_kit/reports/data/format_two_dimensions'
32
32
  require 'reports_kit/reports/data/generate'
33
33
  require 'reports_kit/reports/data/generate_for_properties'
34
+ require 'reports_kit/reports/data/normalize_properties'
34
35
  require 'reports_kit/reports/data/populate_one_dimension'
35
36
  require 'reports_kit/reports/data/populate_two_dimensions'
36
37
  require 'reports_kit/reports/data/utils'
@@ -44,12 +45,14 @@ require 'reports_kit/reports/filter_types/string'
44
45
 
45
46
  require 'reports_kit/reports/abstract_series'
46
47
  require 'reports_kit/reports/composite_series'
48
+ require 'reports_kit/reports/contextual_filter'
47
49
  require 'reports_kit/reports/dimension'
48
50
  require 'reports_kit/reports/dimension_with_series'
49
51
  require 'reports_kit/reports/filter'
50
52
  require 'reports_kit/reports/filter_with_series'
51
53
  require 'reports_kit/reports/generate_autocomplete_results'
52
54
  require 'reports_kit/reports/inferrable_configuration'
55
+ require 'reports_kit/reports/model_settings'
53
56
  require 'reports_kit/reports/properties'
54
57
  require 'reports_kit/reports/properties_to_filter'
55
58
  require 'reports_kit/reports/series'
@@ -6,5 +6,12 @@ module ReportsKit
6
6
  def context_record
7
7
  ReportsKit.configuration.context_record(self)
8
8
  end
9
+
10
+ private
11
+
12
+ def modify_context_params
13
+ modify_context_params_method = ReportsKit.configuration.modify_context_params_method
14
+ params[:context_params] = modify_context_params_method.call(params[:context_params], self) if modify_context_params_method
15
+ end
9
16
  end
10
17
  end
@@ -1,8 +1,8 @@
1
1
  module ReportsKit
2
2
  class Configuration
3
3
  attr_accessor :autocomplete_results_method, :cache_duration, :cache_store, :context_record_method, :custom_methods,
4
- :default_dimension_limit, :default_properties, :first_day_of_week, :properties_method, :report_filename_method,
5
- :use_concurrent_queries
4
+ :default_dimension_limit, :default_properties, :first_day_of_week, :modify_context_params_method, :properties_method,
5
+ :report_filename_method, :use_concurrent_queries
6
6
 
7
7
  DEFAULT_PROPERTIES_METHOD = lambda do |env|
8
8
  path = Rails.root.join('config', 'reports_kit', 'reports', "#{report_key}.yml")
@@ -18,6 +18,7 @@ module ReportsKit
18
18
  self.default_dimension_limit = 30
19
19
  self.default_properties = nil
20
20
  self.first_day_of_week = :sunday
21
+ self.modify_context_params_method = nil
21
22
  self.properties_method = DEFAULT_PROPERTIES_METHOD
22
23
  self.report_filename_method = nil
23
24
  self.use_concurrent_queries = false
@@ -1,5 +1,7 @@
1
1
  module ReportsKit
2
2
  class FiltersController < ReportsKit::BaseController
3
+ before_action :modify_context_params
4
+
3
5
  def autocomplete
4
6
  properties = Reports::Properties.generate(self)
5
7
  results = Reports::GenerateAutocompleteResults.new(params, properties, context_record: context_record).perform
@@ -1,9 +1,10 @@
1
1
  module ReportsKit
2
2
  class ModelConfiguration
3
- attr_accessor :aggregations, :dimensions, :filters
3
+ attr_accessor :aggregations, :contextual_filters, :dimensions, :filters
4
4
 
5
5
  def initialize
6
6
  self.aggregations = []
7
+ self.contextual_filters = []
7
8
  self.dimensions = []
8
9
  self.filters = []
9
10
  end
@@ -12,6 +13,10 @@ module ReportsKit
12
13
  aggregations << { key: key.to_s, expression: expression }.merge(properties).symbolize_keys
13
14
  end
14
15
 
16
+ def contextual_filter(key, method)
17
+ contextual_filters << { key: key, method: method }
18
+ end
19
+
15
20
  def dimension(key, properties)
16
21
  dimensions << { key: key.to_s }.merge(properties).symbolize_keys
17
22
  end
@@ -0,0 +1,19 @@
1
+ module ReportsKit
2
+ module Reports
3
+ class ContextualFilter
4
+ attr_accessor :key, :model_settings
5
+
6
+ delegate :settings_from_model, to: :model_settings
7
+
8
+ def initialize(key, series:)
9
+ self.key = key.to_sym
10
+ self.model_settings = ModelSettings.new(series, :contextual_filters, self.key)
11
+ end
12
+
13
+ def apply(relation, context_params)
14
+ raise ArgumentError.new("contextual_filter with key :#{key} not defined in #{model_class}") if settings_from_model.blank?
15
+ settings_from_model[:method].call(relation, context_params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -4,8 +4,6 @@ module ReportsKit
4
4
  class FormatTable
5
5
  attr_accessor :data, :format, :first_column_label, :report_options
6
6
 
7
- VALID_AGGREGATION_OPERATORS = [:sum]
8
-
9
7
  def initialize(data, format:, first_column_label:, report_options:)
10
8
  self.data = data
11
9
  self.format = format
@@ -6,10 +6,11 @@ module ReportsKit
6
6
 
7
7
  attr_accessor :properties, :context_record
8
8
 
9
- def initialize(properties, context_record: nil)
9
+ def initialize(properties, context_record: nil, context_params: nil)
10
10
  self.properties = properties.deep_symbolize_keys
11
11
  self.properties = ReportsKit.configuration.default_properties.deep_merge(self.properties) if ReportsKit.configuration.default_properties
12
- self.properties = Utils.normalize_properties(self.properties)
12
+ self.properties[:context_params] = context_params if context_params
13
+ self.properties = NormalizeProperties.new(self.properties).perform
13
14
  self.context_record = context_record
14
15
  end
15
16
 
@@ -0,0 +1,62 @@
1
+ module ReportsKit
2
+ module Reports
3
+ module Data
4
+ class NormalizeProperties
5
+ attr_accessor :raw_properties
6
+
7
+ def initialize(raw_properties)
8
+ self.raw_properties = raw_properties.dup
9
+ end
10
+
11
+ def perform
12
+ context_properties = raw_properties.slice(:context_params, :contextual_filters)
13
+ properties = recursively_normalize_properties(raw_properties)
14
+ populate_context_properties(properties, context_properties: context_properties)
15
+ end
16
+
17
+ private
18
+
19
+ def normalize_filters(series_properties, ui_filters)
20
+ series_properties[:filters] = series_properties[:filters].map do |filter_properties|
21
+ filter_properties = { key: filter_properties } if filter_properties.is_a?(String)
22
+ key = filter_properties[:key]
23
+ ui_key = filter_properties[:ui_key]
24
+ value = ui_filters[key.to_sym]
25
+ value ||= ui_filters[ui_key.to_sym] if ui_key
26
+ if value
27
+ filter_properties[:criteria] ||= {}
28
+ filter_properties[:criteria][:value] = value
29
+ end
30
+ filter_properties
31
+ end
32
+ series_properties
33
+ end
34
+
35
+ def recursively_normalize_properties(properties, ui_filters: nil)
36
+ can_have_nesting = properties[:composite_operator].present? || properties[:series].is_a?(Array)
37
+ ui_filters ||= properties[:ui_filters]
38
+ properties[:series] ||= properties.slice(*Series::VALID_KEYS).presence
39
+ properties[:series] = [properties[:series]] if properties[:series].is_a?(Hash) && properties[:series].present?
40
+ return properties if ui_filters.blank? || properties[:series].blank?
41
+ properties[:series] = properties[:series].map do |series_properties|
42
+ series_properties = recursively_normalize_properties(series_properties, ui_filters: ui_filters) if can_have_nesting
43
+ next(series_properties) if series_properties[:filters].blank?
44
+ normalize_filters(series_properties, ui_filters)
45
+ end
46
+ properties
47
+ end
48
+
49
+ def populate_context_properties(properties, context_properties: nil)
50
+ return properties if context_properties.blank? || properties.blank? || properties[:series].blank?
51
+ can_have_nesting = properties[:composite_operator].present? || properties[:series].is_a?(Array)
52
+ properties[:series] = properties[:series].map do |series_properties|
53
+ series_properties = series_properties.merge(context_properties)
54
+ series_properties = populate_context_properties(series_properties, context_properties: context_properties) if can_have_nesting
55
+ series_properties
56
+ end
57
+ properties
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -146,37 +146,6 @@ module ReportsKit
146
146
  formatted_value = value_format_method.call(raw_value) if value_format_method
147
147
  Value.new(raw_value, formatted_value)
148
148
  end
149
-
150
- def self.normalize_filters(series_properties, ui_filters)
151
- series_properties[:filters] = series_properties[:filters].map do |filter_properties|
152
- filter_properties = { key: filter_properties } if filter_properties.is_a?(String)
153
- key = filter_properties[:key]
154
- ui_key = filter_properties[:ui_key]
155
- value = ui_filters[key.to_sym]
156
- value ||= ui_filters[ui_key.to_sym] if ui_key
157
- if value
158
- filter_properties[:criteria] ||= {}
159
- filter_properties[:criteria][:value] = value
160
- end
161
- filter_properties
162
- end
163
- series_properties
164
- end
165
-
166
- def self.normalize_properties(properties, ui_filters: nil)
167
- can_have_nesting = properties[:composite_operator].present? || properties[:series].is_a?(Array)
168
- ui_filters ||= properties[:ui_filters]
169
- properties = properties.dup
170
- properties[:series] ||= properties.slice(*Series::VALID_KEYS).presence
171
- properties[:series] = [properties[:series]] if properties[:series].is_a?(Hash) && properties[:series].present?
172
- return properties if ui_filters.blank? || properties[:series].blank?
173
- properties[:series] = properties[:series].map do |series_properties|
174
- series_properties = normalize_properties(series_properties, ui_filters: ui_filters) if can_have_nesting
175
- next(series_properties) if series_properties[:filters].blank?
176
- normalize_filters(series_properties, ui_filters)
177
- end
178
- properties
179
- end
180
149
  end
181
150
  end
182
151
  end
@@ -9,13 +9,15 @@ module ReportsKit
9
9
  :text
10
10
  ]
11
11
 
12
- attr_accessor :inferrable, :inferrable_type
12
+ attr_accessor :inferrable, :inferrable_type, :model_settings
13
13
 
14
14
  delegate :key, :expression, :series, to: :inferrable
15
+ delegate :model_class, :settings_from_model, to: :model_settings
15
16
 
16
17
  def initialize(inferrable, inferrable_type)
17
18
  self.inferrable = inferrable
18
19
  self.inferrable_type = inferrable_type
20
+ self.model_settings = ModelSettings.new(series, inferrable_type, key)
19
21
  end
20
22
 
21
23
  def configuration_strategy
@@ -47,15 +49,6 @@ module ReportsKit
47
49
  column_type == :datetime
48
50
  end
49
51
 
50
- def settings_from_model
51
- return {} if model_configuration.blank?
52
- return {} if model_configuration.public_send(inferrable_type).blank?
53
- config_hash = model_configuration.public_send(inferrable_type).find do |hash|
54
- hash[:key] == key
55
- end
56
- config_hash || {}
57
- end
58
-
59
52
  def reflection
60
53
  model_class.reflect_on_association(expression.to_sym)
61
54
  end
@@ -118,16 +111,6 @@ module ReportsKit
118
111
  column_type = model_class.columns_hash[expression.to_s].try(:type)
119
112
  return column_type if SUPPORTED_COLUMN_TYPES.include?(column_type)
120
113
  end
121
-
122
- def model_configuration
123
- return unless model_class && model_class.respond_to?(:reports_kit_configuration)
124
- model_class.reports_kit_configuration
125
- end
126
-
127
- def model_class
128
- return unless series
129
- series.model_class
130
- end
131
114
  end
132
115
  end
133
116
  end
@@ -0,0 +1,35 @@
1
+ module ReportsKit
2
+ module Reports
3
+ class ModelSettings
4
+ attr_accessor :series, :model_configuration_type, :key
5
+
6
+ def initialize(series, model_configuration_type, key)
7
+ self.series = series
8
+ self.model_configuration_type = model_configuration_type
9
+ self.key = key
10
+ end
11
+
12
+ def settings_from_model
13
+ return {} if model_configuration.blank?
14
+ config_hashes = model_configuration.public_send(model_configuration_type)
15
+ return {} if config_hashes.blank?
16
+ config_hash = config_hashes.find do |hash|
17
+ hash[:key] == key
18
+ end
19
+ config_hash || {}
20
+ end
21
+
22
+ def model_class
23
+ return unless series
24
+ series.model_class
25
+ end
26
+
27
+ private
28
+
29
+ def model_configuration
30
+ return unless model_class && model_class.respond_to?(:reports_kit_configuration)
31
+ model_class.reports_kit_configuration
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,9 +1,9 @@
1
1
  module ReportsKit
2
2
  module Reports
3
3
  class Series < AbstractSeries
4
- VALID_KEYS = [:measure, :dimensions, :filters, :limit, :report_options]
4
+ VALID_KEYS = [:measure, :dimensions, :contextual_filters, :context_params, :filters, :limit, :context_params, :report_options]
5
5
 
6
- attr_accessor :properties, :dimensions, :filters, :context_record
6
+ attr_accessor :properties, :dimensions, :contextual_filters, :filters, :context_record
7
7
 
8
8
  def initialize(properties, context_record: nil)
9
9
  properties = { measure: properties } if properties.is_a?(String)
@@ -13,6 +13,7 @@ module ReportsKit
13
13
  properties[:measure] = { key: properties[:measure] } if properties[:measure].is_a?(String)
14
14
  raise ArgumentError.new("Measure properties must be a String or Hash, not a #{properties.class.name}: #{properties.inspect}") unless properties.is_a?(Hash)
15
15
 
16
+ contextual_filter_keys = properties[:contextual_filters] || []
16
17
  dimension_hashes = properties[:dimensions] || []
17
18
  dimension_hashes = dimension_hashes.values if dimension_hashes.is_a?(Hash) && dimension_hashes.key?(:'0')
18
19
  filter_hashes = properties[:filters] || []
@@ -22,6 +23,7 @@ module ReportsKit
22
23
  self.context_record = context_record
23
24
  self.dimensions = dimension_hashes.map { |dimension_hash| DimensionWithSeries.new(dimension: Dimension.new(dimension_hash), series: self) }
24
25
  self.filters = filter_hashes.map { |filter_hash| FilterWithSeries.new(filter: Filter.new(filter_hash), series: self) }
26
+ self.contextual_filters = contextual_filter_keys.map { |key| ContextualFilter.new(key, series: self) }
25
27
  end
26
28
 
27
29
  def key
@@ -91,6 +93,9 @@ module ReportsKit
91
93
  filters.each do |filter|
92
94
  relation = filter.apply(relation)
93
95
  end
96
+ contextual_filters.each do |filter|
97
+ relation = filter.apply(relation, properties[:context_params])
98
+ end
94
99
  relation
95
100
  end
96
101
 
@@ -3,6 +3,8 @@ require 'spreadsheet'
3
3
 
4
4
  module ReportsKit
5
5
  class ReportsController < ReportsKit::BaseController
6
+ before_action :modify_context_params
7
+
6
8
  VALID_PARAMS_PROPERTIES_KEYS = [:ui_filters]
7
9
 
8
10
  def index
@@ -35,7 +37,7 @@ module ReportsKit
35
37
  end
36
38
 
37
39
  def report_data
38
- Reports::Data::Generate.new(properties, context_record: context_record).perform
40
+ Reports::Data::Generate.new(properties, context_record: context_record, context_params: context_params).perform
39
41
  end
40
42
 
41
43
  def properties
@@ -1,3 +1,3 @@
1
1
  module ReportsKit
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReportsKit::Reports::Data::Generate do
4
+ subject { described_class.new(properties).perform }
5
+
6
+ let(:repo) { create(:repo) }
7
+ let(:repo2) { create(:repo) }
8
+ let(:chart_data) do
9
+ chart_data = subject[:chart_data].except(:options)
10
+ chart_data[:datasets] = chart_data[:datasets].map do |dataset|
11
+ dataset.except(:backgroundColor, :borderColor)
12
+ end
13
+ chart_data
14
+ end
15
+
16
+ let!(:issues) do
17
+ [
18
+ create(:issue, repo: repo),
19
+ create(:issue, repo: repo),
20
+ create(:issue, repo: repo2)
21
+ ]
22
+ end
23
+
24
+ context 'with a contextual_filter' do
25
+ context 'with context_params' do
26
+ let(:properties) do
27
+ {
28
+ measure: 'issue',
29
+ contextual_filters: %w(for_repo),
30
+ dimensions: %w(repo),
31
+ context_params: { repo_id: repo.id }
32
+ }
33
+ end
34
+
35
+ it 'returns the chart_data' do
36
+ expect(chart_data).to eq({
37
+ labels: [repo.to_s],
38
+ datasets: [{ label: 'Issues', data: [2] }]
39
+ })
40
+ end
41
+ end
42
+
43
+ context 'without context_params' do
44
+ let(:properties) do
45
+ {
46
+ measure: 'issue',
47
+ contextual_filters: %w(for_repo),
48
+ dimensions: %w(repo)
49
+ }
50
+ end
51
+
52
+ it 'returns the chart_data' do
53
+ expect(chart_data).to eq({
54
+ labels: [repo.to_s, repo2.to_s],
55
+ datasets: [{ label: 'Issues', data: [2, 1] }]
56
+ })
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,196 @@
1
+ require 'spec_helper'
2
+
3
+ describe ReportsKit::Reports::Data::NormalizeProperties do
4
+ describe '#perform' do
5
+ let(:normalized_properties) { described_class.new(properties).perform }
6
+ let(:series) { normalized_properties[:series] }
7
+ let(:context_params) { { foo: 'bar' } }
8
+ let(:name) { 'Foo' }
9
+
10
+ context 'without a series key' do
11
+ let(:properties) do
12
+ {
13
+ measure: 'issue',
14
+ dimensions: %w(opened_at)
15
+ }
16
+ end
17
+
18
+ it 'normalizes' do
19
+ expect(series).to eq([properties])
20
+ end
21
+ end
22
+
23
+ context 'with a series key' do
24
+ let(:properties) do
25
+ {
26
+ series: {
27
+ measure: 'issue',
28
+ dimensions: %w(opened_at)
29
+ }
30
+ }
31
+ end
32
+
33
+ it 'normalizes' do
34
+ expect(series).to eq([properties[:series]])
35
+ end
36
+ end
37
+
38
+ context 'with a series array and context_params' do
39
+ let(:properties) do
40
+ {
41
+ series: [{
42
+ measure: 'issue',
43
+ dimensions: %w(opened_at)
44
+ }],
45
+ context_params: context_params
46
+ }
47
+ end
48
+
49
+ it 'normalizes' do
50
+ expect(series).to eq([{
51
+ measure: 'issue',
52
+ dimensions: %w(opened_at),
53
+ context_params: context_params
54
+ }])
55
+ end
56
+ end
57
+
58
+ context 'with a composite series and context_params' do
59
+ let(:properties) do
60
+ {
61
+ name: name,
62
+ composite_operator: '%',
63
+ series: [
64
+ {
65
+ measure: 'issue',
66
+ dimensions: %w(created_at)
67
+ },
68
+ {
69
+ measure: 'tag',
70
+ dimensions: %w(created_at)
71
+ }
72
+ ],
73
+ context_params: context_params
74
+ }
75
+ end
76
+
77
+ it 'copies the context_params to the series' do
78
+ expect(normalized_properties).to eq({
79
+ name: name,
80
+ composite_operator: '%',
81
+ series: [
82
+ {
83
+ measure: 'issue',
84
+ dimensions: %w(created_at),
85
+ context_params: context_params
86
+ },
87
+ {
88
+ measure: 'tag',
89
+ dimensions: %w(created_at),
90
+ context_params: context_params
91
+ }
92
+ ],
93
+ context_params: context_params
94
+ })
95
+ end
96
+ end
97
+
98
+ context 'with a composite series and context_params' do
99
+ let(:properties) do
100
+ {
101
+ series: [
102
+ {
103
+ name: name,
104
+ composite_operator: '+',
105
+ series: [
106
+ {
107
+ measure: 'issue',
108
+ dimensions: %w(created_at)
109
+ }
110
+ ]
111
+ }
112
+ ],
113
+ context_params: context_params
114
+ }
115
+ end
116
+
117
+ it 'copies the context_params to the series' do
118
+ expect(normalized_properties).to eq({
119
+ series: [
120
+ {
121
+ name: name,
122
+ composite_operator: '+',
123
+ series: [
124
+ {
125
+ measure: 'issue',
126
+ dimensions: %w(created_at),
127
+ context_params: context_params
128
+ }
129
+ ],
130
+ context_params: context_params
131
+ }
132
+ ],
133
+ context_params: context_params
134
+ })
135
+ end
136
+ end
137
+
138
+ context 'with a composite series, a series, and context_params' do
139
+ let(:properties) do
140
+ {
141
+ series: [
142
+ {
143
+ measure: 'issue',
144
+ dimensions: %w(opened_at)
145
+ },
146
+ {
147
+ name: name,
148
+ composite_operator: '%',
149
+ series: [
150
+ {
151
+ measure: 'issue',
152
+ dimensions: %w(created_at)
153
+ },
154
+ {
155
+ measure: 'tag',
156
+ dimensions: %w(created_at)
157
+ }
158
+ ]
159
+ }
160
+ ],
161
+ context_params: context_params
162
+ }
163
+ end
164
+
165
+ it 'copies the context_params to the series' do
166
+ expect(normalized_properties).to eq({
167
+ series: [
168
+ {
169
+ measure: 'issue',
170
+ dimensions: %w(opened_at),
171
+ context_params: context_params
172
+ },
173
+ {
174
+ name: name,
175
+ composite_operator: '%',
176
+ series: [
177
+ {
178
+ measure: 'issue',
179
+ dimensions: %w(created_at),
180
+ context_params: context_params
181
+ },
182
+ {
183
+ measure: 'tag',
184
+ dimensions: %w(created_at),
185
+ context_params: context_params
186
+ }
187
+ ],
188
+ context_params: context_params
189
+ }
190
+ ],
191
+ context_params: context_params
192
+ })
193
+ end
194
+ end
195
+ end
196
+ end
@@ -8,6 +8,7 @@ class Issue < ActiveRecord::Base
8
8
 
9
9
  reports_kit do
10
10
  aggregation :average_duration, [:average, REPORTS_KIT_DATABASE_TYPE == :mysql ? 'DATEDIFF(closed_at, opened_at)' : '(closed_at::date - opened_at::date)']
11
+ contextual_filter :for_repo, ->(relation, context_params) { context_params ? relation.where(repo_id: context_params[:repo_id]) : relation }
11
12
  dimension :titleized_state, group: 'issues.state', key_to_label: -> (state) { state.try(:titleize) }
12
13
  end
13
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reports_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Benner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-14 00:00:00.000000000 Z
11
+ date: 2017-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -221,6 +221,7 @@ files:
221
221
  - lib/reports_kit/reports/adapters/mysql.rb
222
222
  - lib/reports_kit/reports/adapters/postgresql.rb
223
223
  - lib/reports_kit/reports/composite_series.rb
224
+ - lib/reports_kit/reports/contextual_filter.rb
224
225
  - lib/reports_kit/reports/data/add_table_aggregations.rb
225
226
  - lib/reports_kit/reports/data/aggregate_composite.rb
226
227
  - lib/reports_kit/reports/data/aggregate_one_dimension.rb
@@ -231,6 +232,7 @@ files:
231
232
  - lib/reports_kit/reports/data/format_two_dimensions.rb
232
233
  - lib/reports_kit/reports/data/generate.rb
233
234
  - lib/reports_kit/reports/data/generate_for_properties.rb
235
+ - lib/reports_kit/reports/data/normalize_properties.rb
234
236
  - lib/reports_kit/reports/data/populate_one_dimension.rb
235
237
  - lib/reports_kit/reports/data/populate_two_dimensions.rb
236
238
  - lib/reports_kit/reports/data/utils.rb
@@ -246,6 +248,7 @@ files:
246
248
  - lib/reports_kit/reports/filter_with_series.rb
247
249
  - lib/reports_kit/reports/generate_autocomplete_results.rb
248
250
  - lib/reports_kit/reports/inferrable_configuration.rb
251
+ - lib/reports_kit/reports/model_settings.rb
249
252
  - lib/reports_kit/reports/properties.rb
250
253
  - lib/reports_kit/reports/properties_to_filter.rb
251
254
  - lib/reports_kit/reports/series.rb
@@ -263,7 +266,9 @@ files:
263
266
  - spec/fixtures/generate_outputs.yml
264
267
  - spec/reports_kit/form_builder_spec.rb
265
268
  - spec/reports_kit/relative_time_spec.rb
269
+ - spec/reports_kit/reports/data/generate/contextual_filters_spec.rb
266
270
  - spec/reports_kit/reports/data/generate_spec.rb
271
+ - spec/reports_kit/reports/data/normalize_properties_spec.rb
267
272
  - spec/reports_kit/reports/dimension_with_series_spec.rb
268
273
  - spec/reports_kit/reports/filter_with_series_spec.rb
269
274
  - spec/spec_helper.rb