reports_kit 0.3.1 → 0.3.2

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/reports_kit/lib/report.js +0 -2
  3. data/config/routes.rb +3 -3
  4. data/gemfiles/mysql.gemfile.lock +3 -3
  5. data/gemfiles/postgresql.gemfile.lock +3 -3
  6. data/lib/reports_kit.rb +5 -2
  7. data/lib/reports_kit/base_controller.rb +3 -3
  8. data/lib/reports_kit/configuration.rb +5 -0
  9. data/lib/reports_kit/filters_controller.rb +9 -0
  10. data/lib/reports_kit/form_builder.rb +10 -39
  11. data/lib/reports_kit/helper.rb +3 -13
  12. data/lib/reports_kit/model_configuration.rb +1 -6
  13. data/lib/reports_kit/normalized_params.rb +16 -0
  14. data/lib/reports_kit/report_builder.rb +3 -2
  15. data/lib/reports_kit/reports/composite_series.rb +4 -3
  16. data/lib/reports_kit/reports/data/aggregate_composite.rb +1 -1
  17. data/lib/reports_kit/reports/data/generate_for_properties.rb +1 -1
  18. data/lib/reports_kit/reports/filter_with_series.rb +4 -0
  19. data/lib/reports_kit/reports/generate_autocomplete_results.rb +5 -20
  20. data/lib/reports_kit/reports/inferrable_configuration.rb +1 -1
  21. data/lib/reports_kit/reports/properties.rb +10 -0
  22. data/lib/reports_kit/reports/properties_to_filter.rb +40 -0
  23. data/lib/reports_kit/reports/series.rb +7 -2
  24. data/lib/reports_kit/reports_controller.rb +1 -15
  25. data/lib/reports_kit/version.rb +1 -1
  26. data/spec/factories/pro_repo_factory.rb +5 -0
  27. data/spec/reports_kit/reports/data/generate_spec.rb +27 -0
  28. data/spec/spec_helper.rb +4 -3
  29. data/spec/support/models/pro/repo.rb +5 -0
  30. data/spec/support/models/pro/special_issue.rb +4 -0
  31. metadata +9 -33
  32. data/docs/README.md +0 -8
  33. data/docs/dimensions.md +0 -110
  34. data/docs/display_options.md +0 -80
  35. data/docs/filters.md +0 -216
  36. data/docs/images/chart_options.png +0 -0
  37. data/docs/images/dashed_line.png +0 -0
  38. data/docs/images/demo_area.png +0 -0
  39. data/docs/images/demo_dashed_line.png +0 -0
  40. data/docs/images/demo_horizontal_stacked.png +0 -0
  41. data/docs/images/demo_legend.png +0 -0
  42. data/docs/images/demo_multiautocomplete.png +0 -0
  43. data/docs/images/demo_radar.png +0 -0
  44. data/docs/images/flights_by_carrier.png +0 -0
  45. data/docs/images/flights_by_carrier_and_flight_at.png +0 -0
  46. data/docs/images/flights_by_delay.png +0 -0
  47. data/docs/images/flights_by_flight_at.png +0 -0
  48. data/docs/images/flights_by_hours_delayed.png +0 -0
  49. data/docs/images/flights_with_check_box.png +0 -0
  50. data/docs/images/flights_with_configured_boolean.png +0 -0
  51. data/docs/images/flights_with_configured_datetime.png +0 -0
  52. data/docs/images/flights_with_configured_number.png +0 -0
  53. data/docs/images/flights_with_configured_string.png +0 -0
  54. data/docs/images/flights_with_date_range.png +0 -0
  55. data/docs/images/flights_with_filters.png +0 -0
  56. data/docs/images/flights_with_multi_autocomplete.png +0 -0
  57. data/docs/images/flights_with_string_filter.png +0 -0
  58. data/docs/images/horizontal_bar.png +0 -0
  59. data/docs/images/legend_right.png +0 -0
  60. data/docs/images/users_by_created_at_with_filter.png +0 -0
  61. data/docs/measures.md +0 -12
  62. data/lib/reports_kit/resources_controller.rb +0 -8
@@ -0,0 +1,10 @@
1
+ module ReportsKit
2
+ module Reports
3
+ class Properties
4
+ def self.generate(context)
5
+ properties = context.instance_eval(&ReportsKit.configuration.properties_method)
6
+ properties.deep_symbolize_keys
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ module ReportsKit
2
+ module Reports
3
+ class PropertiesToFilter
4
+ attr_accessor :properties, :context_record
5
+
6
+ def initialize(properties, context_record: nil)
7
+ self.properties = properties
8
+ self.context_record = context_record
9
+ end
10
+
11
+ def perform(filter_key)
12
+ filter_key = filter_key.to_s
13
+ filter = filters.find { |f| f.key == filter_key }
14
+ raise ArgumentError.new("A filter with key '#{filter_key}' is not configured in this report") unless filter
15
+ filter
16
+ end
17
+
18
+ private
19
+
20
+ def filters
21
+ @filters ||= ui_filters + series_filters
22
+ end
23
+
24
+ def series_filters
25
+ serieses.map(&:filters).flatten
26
+ end
27
+
28
+ def ui_filters
29
+ return [] if properties[:ui_filters].blank?
30
+ properties[:ui_filters].map do |ui_filter_properties|
31
+ Reports::Filter.new(ui_filter_properties)
32
+ end
33
+ end
34
+
35
+ def serieses
36
+ Reports::Series.new_from_properties!(properties, context_record: context_record)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -19,9 +19,9 @@ module ReportsKit
19
19
  filter_hashes = filter_hashes.values if filter_hashes.is_a?(Hash) && filter_hashes.key?(:'0')
20
20
 
21
21
  self.properties = properties
22
+ self.context_record = context_record
22
23
  self.dimensions = dimension_hashes.map { |dimension_hash| DimensionWithSeries.new(dimension: Dimension.new(dimension_hash), series: self) }
23
24
  self.filters = filter_hashes.map { |filter_hash| FilterWithSeries.new(filter: Filter.new(filter_hash), series: self) }
24
- self.context_record = context_record
25
25
  end
26
26
 
27
27
  def key
@@ -78,6 +78,11 @@ module ReportsKit
78
78
  end
79
79
 
80
80
  def model_class
81
+ if context_record
82
+ reflection = context_record.class.reflect_on_association(key.to_sym) ||
83
+ context_record.class.reflect_on_association(key.pluralize.to_sym)
84
+ return reflection.klass if reflection
85
+ end
81
86
  key.camelize.constantize
82
87
  end
83
88
 
@@ -100,7 +105,7 @@ module ReportsKit
100
105
 
101
106
  series_hashes.map do |series_hash|
102
107
  if series_hash[:composite_operator].present?
103
- CompositeSeries.new(series_hash)
108
+ CompositeSeries.new(series_hash, context_record: context_record)
104
109
  else
105
110
  new(series_hash, context_record: context_record)
106
111
  end
@@ -26,19 +26,6 @@ module ReportsKit
26
26
  end
27
27
  end
28
28
 
29
- def report_params
30
- params[:report_params]
31
- end
32
-
33
- def context_params
34
- params[:context_params]
35
- end
36
-
37
- def report_key
38
- raise ArgumentError.new('Blank report_params') if report_params.blank?
39
- report_params[:key]
40
- end
41
-
42
29
  private
43
30
 
44
31
  def report_filename
@@ -53,8 +40,7 @@ module ReportsKit
53
40
 
54
41
  def properties
55
42
  @properties ||= begin
56
- properties_method = ReportsKit.configuration.properties_method
57
- properties = instance_eval(&properties_method)
43
+ properties = Reports::Properties.generate(self)
58
44
  properties.merge(params_properties).deep_symbolize_keys
59
45
  end
60
46
  end
@@ -1,3 +1,3 @@
1
1
  module ReportsKit
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :pro_repo, class: Pro::Repo do
3
+ sequence(:full_name) { |i| "foo/bar#{i}" }
4
+ end
5
+ end
@@ -307,6 +307,33 @@ describe ReportsKit::Reports::Data::Generate do
307
307
  datasets: [{ label: 'Issues', data: [2.0] }]
308
308
  })
309
309
  end
310
+
311
+ context 'with a namespaced context_record class' do
312
+ let(:pro_repo) { create(:pro_repo) }
313
+ let(:context_record) { pro_repo }
314
+ let(:properties) do
315
+ {
316
+ measure: 'special_issue',
317
+ dimensions: %w(repo)
318
+ }
319
+ end
320
+
321
+ let!(:issues) do
322
+ [
323
+ create(:issue, repo: pro_repo),
324
+ create(:issue, repo: pro_repo),
325
+ create(:issue, repo: pro_repo),
326
+ create(:issue, repo: repo2)
327
+ ]
328
+ end
329
+
330
+ it 'returns the chart_data' do
331
+ expect(chart_data).to eq({
332
+ labels: [pro_repo.to_s],
333
+ datasets: [{ label: 'Special Issues', data: [3.0] }]
334
+ })
335
+ end
336
+ end
310
337
  end
311
338
 
312
339
  context 'with a limit' do
@@ -7,9 +7,6 @@ require 'timecop'
7
7
  require 'support/factory_girl'
8
8
  require 'support/helpers'
9
9
 
10
- directory = File.dirname(File.absolute_path(__FILE__))
11
- Dir.glob("#{directory}/factories/*.rb") { |file| require file }
12
-
13
10
  Time.zone = ActiveSupport::TimeZone.new('UTC')
14
11
  ActiveRecord::Base.default_timezone = :utc
15
12
 
@@ -32,7 +29,11 @@ else
32
29
  username: 'postgres'
33
30
  )
34
31
  end
32
+ directory = File.dirname(File.absolute_path(__FILE__))
35
33
  Dir.glob("#{directory}/support/models/*.rb") { |file| require file }
34
+ Dir.glob("#{directory}/support/models/**/*.rb") { |file| require file }
35
+ Dir.glob("#{directory}/factories/*.rb") { |file| require file }
36
+
36
37
  require 'support/config'
37
38
  require 'support/schema'
38
39
 
@@ -0,0 +1,5 @@
1
+ module Pro
2
+ class Repo < ::Repo
3
+ has_many :special_issues
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Pro
2
+ class SpecialIssue < ::Issue
3
+ end
4
+ 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.1
4
+ version: 0.3.2
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-09-02 00:00:00.000000000 Z
11
+ date: 2017-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -184,38 +184,8 @@ files:
184
184
  - app/assets/stylesheets/reports_kit/vendor/select2.css
185
185
  - config/initializers/mime_types.rb
186
186
  - config/routes.rb
187
- - docs/README.md
188
- - docs/dimensions.md
189
- - docs/display_options.md
190
- - docs/filters.md
191
- - docs/images/chart_options.png
192
- - docs/images/dashed_line.png
193
187
  - docs/images/demo.gif
194
- - docs/images/demo_area.png
195
- - docs/images/demo_dashed_line.png
196
- - docs/images/demo_horizontal_stacked.png
197
- - docs/images/demo_legend.png
198
- - docs/images/demo_multiautocomplete.png
199
- - docs/images/demo_radar.png
200
- - docs/images/flights_by_carrier.png
201
- - docs/images/flights_by_carrier_and_flight_at.png
202
- - docs/images/flights_by_delay.png
203
- - docs/images/flights_by_flight_at.png
204
- - docs/images/flights_by_hours_delayed.png
205
- - docs/images/flights_with_check_box.png
206
- - docs/images/flights_with_configured_boolean.png
207
- - docs/images/flights_with_configured_datetime.png
208
- - docs/images/flights_with_configured_number.png
209
- - docs/images/flights_with_configured_string.png
210
- - docs/images/flights_with_date_range.png
211
- - docs/images/flights_with_filters.png
212
- - docs/images/flights_with_multi_autocomplete.png
213
- - docs/images/flights_with_string_filter.png
214
- - docs/images/horizontal_bar.png
215
- - docs/images/legend_right.png
216
188
  - docs/images/users_by_created_at.png
217
- - docs/images/users_by_created_at_with_filter.png
218
- - docs/measures.md
219
189
  - gemfiles/mysql.gemfile
220
190
  - gemfiles/mysql.gemfile.lock
221
191
  - gemfiles/postgresql.gemfile
@@ -226,10 +196,12 @@ files:
226
196
  - lib/reports_kit/configuration.rb
227
197
  - lib/reports_kit/engine.rb
228
198
  - lib/reports_kit/entity.rb
199
+ - lib/reports_kit/filters_controller.rb
229
200
  - lib/reports_kit/form_builder.rb
230
201
  - lib/reports_kit/helper.rb
231
202
  - lib/reports_kit/model.rb
232
203
  - lib/reports_kit/model_configuration.rb
204
+ - lib/reports_kit/normalized_params.rb
233
205
  - lib/reports_kit/order.rb
234
206
  - lib/reports_kit/relative_time.rb
235
207
  - lib/reports_kit/report_builder.rb
@@ -262,15 +234,17 @@ files:
262
234
  - lib/reports_kit/reports/filter_with_series.rb
263
235
  - lib/reports_kit/reports/generate_autocomplete_results.rb
264
236
  - lib/reports_kit/reports/inferrable_configuration.rb
237
+ - lib/reports_kit/reports/properties.rb
238
+ - lib/reports_kit/reports/properties_to_filter.rb
265
239
  - lib/reports_kit/reports/series.rb
266
240
  - lib/reports_kit/reports_controller.rb
267
- - lib/reports_kit/resources_controller.rb
268
241
  - lib/reports_kit/value.rb
269
242
  - lib/reports_kit/version.rb
270
243
  - reports_kit.gemspec
271
244
  - spec/factories/issue_factory.rb
272
245
  - spec/factories/issues_label_factory.rb
273
246
  - spec/factories/label_factory.rb
247
+ - spec/factories/pro_repo_factory.rb
274
248
  - spec/factories/repo_factory.rb
275
249
  - spec/factories/tag_factory.rb
276
250
  - spec/fixtures/generate_inputs.yml
@@ -287,6 +261,8 @@ files:
287
261
  - spec/support/models/issue.rb
288
262
  - spec/support/models/issues_label.rb
289
263
  - spec/support/models/label.rb
264
+ - spec/support/models/pro/repo.rb
265
+ - spec/support/models/pro/special_issue.rb
290
266
  - spec/support/models/repo.rb
291
267
  - spec/support/models/tag.rb
292
268
  - spec/support/schema.rb
@@ -1,8 +0,0 @@
1
- Documentation
2
- -------------
3
-
4
- 1. [Measures](measures.md)
5
- 1. [Dimensions](dimensions.md)
6
- 1. [Filters](filters.md)
7
- 1. [Display Options](display_options.md)
8
- 1. [Examples](https://www.reportskit.co/)
@@ -1,110 +0,0 @@
1
- ### Dimensions
2
-
3
- #### Overview
4
-
5
- The dimension is what the measure is being grouped by. You can use datetime columns, integer columns, string columns, associations, or even define custom dimensions.
6
-
7
- For example, say you have a `Flight` model with a `belongs_to :carrier` association:
8
-
9
- ```ruby
10
- class Flight < ActiveRecord::Base
11
- belongs_to :carrier
12
- end
13
- ```
14
-
15
- You can then use `dimensions: ['carrier']` to count the number of Flights per Carrier:
16
-
17
- ```yaml
18
- measure: flight
19
- dimensions:
20
- - carrier
21
- ```
22
- [<img src="images/flights_by_carrier.png?raw=true" width="500" />](images/flights_by_carrier.png?raw=true)
23
-
24
- You can also use two dimensions:
25
-
26
- ```yaml
27
- measure: flight
28
- dimensions:
29
- - carrier
30
- - flight_at
31
- ```
32
- [<img src="images/flights_by_carrier_and_flight_at.png?raw=true" width="500" />](images/flights_by_carrier_and_flight_at.png?raw=true)
33
-
34
- Dimensions can be configured using a string (`carrier`):
35
-
36
- ```yaml
37
- measure: flight
38
- dimensions:
39
- - carrier
40
- ```
41
-
42
- Or, if you need to use options, you can configure them using a hash:
43
-
44
- ```yaml
45
- measure: flight
46
- dimensions:
47
- - key: carrier
48
- limit: 5
49
- ```
50
- #### Types
51
-
52
- ##### Association
53
-
54
- ```yaml
55
- measure: flight
56
- dimensions:
57
- - carrier
58
- ```
59
- [<img src="images/flights_by_carrier.png?raw=true" width="500" />](images/flights_by_carrier.png?raw=true)
60
-
61
- ##### Datetime Column
62
-
63
- ```yaml
64
- measure: flight
65
- dimensions:
66
- - flight_at
67
- ```
68
- [<img src="images/flights_by_flight_at.png?raw=true" width="500" />](images/flights_by_flight_at.png?raw=true)
69
-
70
- ##### Integer Column
71
-
72
- ```yaml
73
- measure: flight
74
- dimensions:
75
- - delay
76
- ```
77
- [<img src="images/flights_by_delay.png?raw=true" width="500" />](images/flights_by_delay.png?raw=true)
78
-
79
- ##### Custom Dimensions
80
-
81
- You can define custom dimensions in your model. For example, if `Flight` has a column named `delay` (in minutes), we can define a `hours_delayed` dimension:
82
-
83
- ```ruby
84
- class Flight < ApplicationRecord
85
- include ReportsKit::Model
86
-
87
- reports_kit do
88
- dimension :hours_delayed, group: 'GREATEST(ROUND(flights.delay::float/60), 0)'
89
- end
90
- end
91
- ```
92
-
93
- We can then use the `hours_delayed` dimension:
94
-
95
- ```yaml
96
- measure: flight
97
- dimensions:
98
- - hours_delayed
99
- ```
100
- [<img src="images/flights_by_hours_delayed.png?raw=true" width="500" />](images/flights_by_hours_delayed.png?raw=true)
101
-
102
- #### Options
103
-
104
- ##### `key` *String*
105
-
106
- The dimension's identifier. You can use association names (e.g. `author`), column names (e.g. `created_at`), or the keys of custom dimensions (e.g. `my_dimension`).
107
-
108
- ##### `limit` *Integer*
109
-
110
- The maximum number of dimension instances to include. For example, if you set `limit: 5` and have one dimension, then the x-axis will only show 5 items.
@@ -1,80 +0,0 @@
1
- ### Display Options
2
-
3
- #### Overview
4
-
5
- Charts are rendered using [Chart.js](http://www.chartjs.org/). You can configure your ReportsKit chart using any [Chart.js options](http://www.chartjs.org/docs/).
6
-
7
- ##### `type`
8
-
9
- You can use any `type` value supported by Chart.js, including `bar`, `line`, `horizontalBar`, `radar`, and more.
10
-
11
- Here's an example of a horizontal bar chart:
12
-
13
- ```yaml
14
- measure: flight
15
- dimensions:
16
- - carrier
17
- chart:
18
- type: horizontalBar
19
- options:
20
- scales:
21
- xAxes:
22
- - scaleLabel:
23
- display: true
24
- labelString: Flights
25
- yAxes:
26
- - scaleLabel:
27
- display: true
28
- labelString: Carrier
29
- ```
30
- [<img src="images/horizontal_bar.png?raw=true" width="500" />](images/horizontal_bar.png?raw=true)
31
-
32
- ##### `options`
33
-
34
- You can use any `options` that are supported by Chart.js.
35
-
36
- Here's an example of a chart with Chart.js options:
37
-
38
- ```yaml
39
- measure: flight
40
- dimensions:
41
- - origin_market
42
- - carrier
43
- chart:
44
- type: horizontalBar
45
- options:
46
- scales:
47
- xAxes:
48
- - stacked: true
49
- scaleLabel:
50
- display: true
51
- labelString: Flights
52
- yAxes:
53
- - stacked: true
54
- scaleLabel:
55
- display: true
56
- labelString: Market
57
- ```
58
- [<img src="images/chart_options.png?raw=true" width="500" />](images/chart_options.png?raw=true)
59
-
60
- ##### `datasets`
61
-
62
- You can use any `datasets` options that are supported by Chart.js.
63
-
64
- Here's an example of a chart with `datasets` options:
65
-
66
- ```yaml
67
- measure: flight
68
- dimensions:
69
- - flight_at
70
- - key: carrier
71
- limit: 3
72
- chart:
73
- type: line
74
- datasets:
75
- fill: false
76
- borderDash:
77
- - 5
78
- - 5
79
- ```
80
- [<img src="images/dashed_line.png?raw=true" width="500" />](images/dashed_line.png?raw=true)