reports_kit 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|