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 +4 -4
- data/gemfiles/rails_4_mysql.gemfile.lock +1 -1
- data/gemfiles/rails_4_postgresql.gemfile.lock +1 -1
- data/gemfiles/rails_5.1.4_postgresql.gemfile.lock +1 -1
- data/gemfiles/rails_5_mysql.gemfile.lock +1 -1
- data/gemfiles/rails_5_postgresql.gemfile.lock +1 -1
- data/lib/reports_kit.rb +3 -0
- data/lib/reports_kit/base_controller.rb +7 -0
- data/lib/reports_kit/configuration.rb +3 -2
- data/lib/reports_kit/filters_controller.rb +2 -0
- data/lib/reports_kit/model_configuration.rb +6 -1
- data/lib/reports_kit/reports/contextual_filter.rb +19 -0
- data/lib/reports_kit/reports/data/format_table.rb +0 -2
- data/lib/reports_kit/reports/data/generate.rb +3 -2
- data/lib/reports_kit/reports/data/normalize_properties.rb +62 -0
- data/lib/reports_kit/reports/data/utils.rb +0 -31
- data/lib/reports_kit/reports/inferrable_configuration.rb +3 -20
- data/lib/reports_kit/reports/model_settings.rb +35 -0
- data/lib/reports_kit/reports/series.rb +7 -2
- data/lib/reports_kit/reports_controller.rb +3 -1
- data/lib/reports_kit/version.rb +1 -1
- data/spec/reports_kit/reports/data/generate/contextual_filters_spec.rb +60 -0
- data/spec/reports_kit/reports/data/normalize_properties_spec.rb +196 -0
- data/spec/support/models/issue.rb +1 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13094de820c79cec7858078fa4c307a0137c001f
|
4
|
+
data.tar.gz: 971b1281d81369b1539aad7c4ac977a72c66558b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c2d64e334083cb58173e9d3ae7daa4453a45c2f6715bf971ea01bc5b1f1b4a0d01bcddf4abc50c7acdaa2d2cedf31bc78ddbe16e1f8e97e363f0200fe53f8e4
|
7
|
+
data.tar.gz: f666b9e785d28c22754f8fd6e3fe178f04f3add4599b3b0673240e15d3ea7547a051e952ae683b3a334a6de6d43e24bcb062c86a95c61646e74f916aa9064691
|
data/lib/reports_kit.rb
CHANGED
@@ -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, :
|
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
|
@@ -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 =
|
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
|
data/lib/reports_kit/version.rb
CHANGED
@@ -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.
|
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-
|
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
|