reports_kits 0.7.5 → 0.7.7

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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.rubocop.yml +85 -0
  4. data/.travis.yml +21 -0
  5. data/Appraisals +27 -0
  6. data/Gemfile +3 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +35 -0
  9. data/Rakefile +2 -0
  10. data/app/assets/javascripts/reports_kits/application.js +14 -0
  11. data/app/assets/javascripts/reports_kits/lib/_init.js +9 -0
  12. data/app/assets/javascripts/reports_kits/lib/chart.js +73 -0
  13. data/app/assets/javascripts/reports_kits/lib/report.js +135 -0
  14. data/app/assets/javascripts/reports_kits/lib/table.js +87 -0
  15. data/app/assets/javascripts/reports_kits/vendor/chart.js +12269 -0
  16. data/app/assets/javascripts/reports_kits/vendor/daterangepicker.js +1627 -0
  17. data/app/assets/javascripts/reports_kits/vendor/jquery.tablesorter.min.js +4 -0
  18. data/app/assets/javascripts/reports_kits/vendor/moment.js +4040 -0
  19. data/app/assets/javascripts/reports_kits/vendor/select2.full.js +6436 -0
  20. data/app/assets/stylesheets/reports_kits/application.css.scss +3 -0
  21. data/app/assets/stylesheets/reports_kits/reports.css.sass +33 -0
  22. data/app/assets/stylesheets/reports_kits/select2_overrides.css.sass +7 -0
  23. data/app/assets/stylesheets/reports_kits/vendor/daterangepicker.css +269 -0
  24. data/app/assets/stylesheets/reports_kits/vendor/select2-bootstrap.css +721 -0
  25. data/app/assets/stylesheets/reports_kits/vendor/select2.css +484 -0
  26. data/config/initializers/mime_types.rb +1 -0
  27. data/config/routes.rb +10 -0
  28. data/docs/images/demo.gif +0 -0
  29. data/docs/images/users_by_created_at.png +0 -0
  30. data/gemfiles/mysql.gemfile +7 -0
  31. data/gemfiles/mysql.gemfile.lock +167 -0
  32. data/gemfiles/postgresql.gemfile +7 -0
  33. data/gemfiles/postgresql.gemfile.lock +165 -0
  34. data/gemfiles/postgresql_rails_5.1.4.gemfile +8 -0
  35. data/gemfiles/postgresql_rails_5.1.4.gemfile.lock +168 -0
  36. data/gemfiles/rails_4_mysql.gemfile +8 -0
  37. data/gemfiles/rails_4_mysql.gemfile.lock +165 -0
  38. data/gemfiles/rails_4_postgresql.gemfile +8 -0
  39. data/gemfiles/rails_4_postgresql.gemfile.lock +163 -0
  40. data/gemfiles/rails_5.1.4_postgresql.gemfile +8 -0
  41. data/gemfiles/rails_5.1.4_postgresql.gemfile.lock +169 -0
  42. data/gemfiles/rails_5_mysql.gemfile +8 -0
  43. data/gemfiles/rails_5_mysql.gemfile.lock +171 -0
  44. data/gemfiles/rails_5_postgresql.gemfile +8 -0
  45. data/gemfiles/rails_5_postgresql.gemfile.lock +169 -0
  46. data/lib/reports_kits/base_controller.rb +17 -0
  47. data/lib/reports_kits/cache.rb +37 -0
  48. data/lib/reports_kits/configuration.rb +50 -0
  49. data/lib/reports_kits/engine.rb +21 -0
  50. data/lib/reports_kits/entity.rb +3 -0
  51. data/lib/reports_kits/filters_controller.rb +11 -0
  52. data/lib/reports_kits/form_builder.rb +66 -0
  53. data/lib/reports_kits/helper.rb +24 -0
  54. data/lib/reports_kits/model.rb +16 -0
  55. data/lib/reports_kits/model_configuration.rb +28 -0
  56. data/lib/reports_kits/normalized_params.rb +16 -0
  57. data/lib/reports_kits/order.rb +33 -0
  58. data/lib/reports_kits/relative_time.rb +42 -0
  59. data/lib/reports_kits/report_builder.rb +88 -0
  60. data/lib/reports_kits/reports/abstract_series.rb +9 -0
  61. data/lib/reports_kits/reports/adapters/mysql.rb +26 -0
  62. data/lib/reports_kits/reports/adapters/postgresql.rb +26 -0
  63. data/lib/reports_kits/reports/composite_series.rb +48 -0
  64. data/lib/reports_kits/reports/contextual_filter.rb +19 -0
  65. data/lib/reports_kits/reports/data/add_table_aggregations.rb +105 -0
  66. data/lib/reports_kits/reports/data/aggregate_composite.rb +97 -0
  67. data/lib/reports_kits/reports/data/aggregate_one_dimension.rb +39 -0
  68. data/lib/reports_kits/reports/data/aggregate_two_dimensions.rb +39 -0
  69. data/lib/reports_kits/reports/data/chart_data_for_data_method.rb +62 -0
  70. data/lib/reports_kits/reports/data/chart_options.rb +155 -0
  71. data/lib/reports_kits/reports/data/format_one_dimension.rb +140 -0
  72. data/lib/reports_kits/reports/data/format_table.rb +63 -0
  73. data/lib/reports_kits/reports/data/format_two_dimensions.rb +143 -0
  74. data/lib/reports_kits/reports/data/generate.rb +156 -0
  75. data/lib/reports_kits/reports/data/generate_for_properties.rb +97 -0
  76. data/lib/reports_kits/reports/data/normalize_properties.rb +62 -0
  77. data/lib/reports_kits/reports/data/populate_one_dimension.rb +54 -0
  78. data/lib/reports_kits/reports/data/populate_two_dimensions.rb +104 -0
  79. data/lib/reports_kits/reports/data/utils.rb +178 -0
  80. data/lib/reports_kits/reports/dimension.rb +27 -0
  81. data/lib/reports_kits/reports/dimension_with_series.rb +144 -0
  82. data/lib/reports_kits/reports/filter.rb +29 -0
  83. data/lib/reports_kits/reports/filter_types/base.rb +48 -0
  84. data/lib/reports_kits/reports/filter_types/boolean.rb +47 -0
  85. data/lib/reports_kits/reports/filter_types/datetime.rb +51 -0
  86. data/lib/reports_kits/reports/filter_types/number.rb +30 -0
  87. data/lib/reports_kits/reports/filter_types/records.rb +26 -0
  88. data/lib/reports_kits/reports/filter_types/string.rb +38 -0
  89. data/lib/reports_kits/reports/filter_with_series.rb +97 -0
  90. data/lib/reports_kits/reports/generate_autocomplete_method_results.rb +29 -0
  91. data/lib/reports_kits/reports/generate_autocomplete_results.rb +57 -0
  92. data/lib/reports_kits/reports/inferrable_configuration.rb +116 -0
  93. data/lib/reports_kits/reports/model_settings.rb +30 -0
  94. data/lib/reports_kits/reports/properties.rb +10 -0
  95. data/lib/reports_kits/reports/properties_to_filter.rb +40 -0
  96. data/lib/reports_kits/reports/series.rb +121 -0
  97. data/lib/reports_kits/reports_controller.rb +65 -0
  98. data/lib/reports_kits/utils.rb +11 -0
  99. data/lib/reports_kits/value.rb +3 -0
  100. data/lib/reports_kits/version.rb +3 -0
  101. data/lib/reports_kits.rb +79 -0
  102. data/reports_kits.gemspec +26 -0
  103. data/spec/factories/issue_factory.rb +4 -0
  104. data/spec/factories/issues_label_factory.rb +4 -0
  105. data/spec/factories/label_factory.rb +4 -0
  106. data/spec/factories/pro_repo_factory.rb +5 -0
  107. data/spec/factories/repo_factory.rb +5 -0
  108. data/spec/factories/tag_factory.rb +4 -0
  109. data/spec/fixtures/generate_inputs.yml +254 -0
  110. data/spec/fixtures/generate_outputs.yml +1216 -0
  111. data/spec/reports_kit/form_builder_spec.rb +26 -0
  112. data/spec/reports_kit/relative_time_spec.rb +29 -0
  113. data/spec/reports_kit/reports/data/generate/contextual_filters_spec.rb +60 -0
  114. data/spec/reports_kit/reports/data/generate_spec.rb +1371 -0
  115. data/spec/reports_kit/reports/data/normalize_properties_spec.rb +196 -0
  116. data/spec/reports_kit/reports/dimension_with_series_spec.rb +67 -0
  117. data/spec/reports_kit/reports/filter_with_series_spec.rb +39 -0
  118. data/spec/reports_kit/reports/generate_autocomplete_results_spec.rb +69 -0
  119. data/spec/spec_helper.rb +77 -0
  120. data/spec/support/config.rb +41 -0
  121. data/spec/support/example_data_methods.rb +25 -0
  122. data/spec/support/factory_girl.rb +5 -0
  123. data/spec/support/helpers.rb +25 -0
  124. data/spec/support/models/issue.rb +14 -0
  125. data/spec/support/models/issues_label.rb +4 -0
  126. data/spec/support/models/label.rb +5 -0
  127. data/spec/support/models/pro/repo.rb +5 -0
  128. data/spec/support/models/pro/special_issue.rb +4 -0
  129. data/spec/support/models/repo.rb +13 -0
  130. data/spec/support/models/tag.rb +4 -0
  131. data/spec/support/schema.rb +39 -0
  132. metadata +134 -4
@@ -0,0 +1,116 @@
1
+ module ReportsKits
2
+ module Reports
3
+ class InferrableConfiguration
4
+ SUPPORTED_COLUMN_TYPES = [
5
+ :boolean,
6
+ :datetime,
7
+ :integer,
8
+ :string,
9
+ :text
10
+ ]
11
+
12
+ attr_accessor :inferrable, :inferrable_type, :model_settings
13
+
14
+ delegate :key, :expression, :series, to: :inferrable
15
+ delegate :model_class, :settings_from_model, to: :model_settings
16
+
17
+ def initialize(inferrable, inferrable_type)
18
+ self.inferrable = inferrable
19
+ self.inferrable_type = inferrable_type
20
+ self.model_settings = ModelSettings.new(series.model_class, inferrable_type, key)
21
+ end
22
+
23
+ def configuration_strategy
24
+ if settings_from_model.present?
25
+ :model
26
+ elsif reflection
27
+ :association
28
+ elsif column_type
29
+ :column
30
+ else
31
+ inferrable_type_string = inferrable_type.to_s.singularize
32
+ raise ArgumentError.new("No configuration found on the #{model_class} model for #{inferrable_type_string} with key: '#{key}'")
33
+ end
34
+ end
35
+
36
+ def configured_by_association?
37
+ configuration_strategy == :association
38
+ end
39
+
40
+ def configured_by_column?
41
+ configuration_strategy == :column
42
+ end
43
+
44
+ def configured_by_model?
45
+ configuration_strategy == :model
46
+ end
47
+
48
+ def configured_by_time?
49
+ column_type == :datetime
50
+ end
51
+
52
+ def reflection
53
+ model_class.reflect_on_association(expression.to_sym)
54
+ end
55
+
56
+ def instance_class
57
+ return reflection.klass if reflection
58
+ nil
59
+ end
60
+
61
+ def column
62
+ return unless inferred_settings
63
+ inferred_settings[:column]
64
+ end
65
+
66
+ def inferred_settings
67
+ return { column: "#{model_class.table_name}.#{expression}" } if configured_by_column?
68
+ if configured_by_association?
69
+ return inferred_settings_from_belongs_to_or_has_one if inferred_settings_from_belongs_to_or_has_one
70
+ return inferred_settings_from_has_many if inferred_settings_from_has_many
71
+ end
72
+ {}
73
+ end
74
+
75
+ def inferred_settings_from_belongs_to_or_has_one
76
+ @inferred_settings_from_belongs_to_or_has_one ||= begin
77
+ return unless reflection.macro.in?([:belongs_to, :has_one])
78
+ through_reflection = reflection.through_reflection
79
+ if through_reflection
80
+ {
81
+ joins: through_reflection.name,
82
+ column: "#{through_reflection.table_name}.#{reflection.source_reflection.foreign_key}"
83
+ }
84
+ else
85
+ {
86
+ column: "#{model_class.table_name}.#{reflection.foreign_key}"
87
+ }
88
+ end
89
+ end
90
+ end
91
+
92
+ def inferred_settings_from_has_many
93
+ @inferred_settings_from_has_many ||= begin
94
+ return unless reflection.macro == :has_many
95
+ through_reflection = reflection.through_reflection
96
+ if through_reflection
97
+ {
98
+ joins: through_reflection.name,
99
+ column: "#{through_reflection.table_name}.#{reflection.source_reflection.foreign_key}"
100
+ }
101
+ else
102
+ {
103
+ joins: reflection.name,
104
+ column: "#{reflection.klass.table_name}.#{reflection.klass.primary_key}"
105
+ }
106
+ end
107
+ end
108
+ end
109
+
110
+ def column_type
111
+ column_type = model_class.columns_hash[expression.to_s].try(:type)
112
+ return column_type if SUPPORTED_COLUMN_TYPES.include?(column_type)
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,30 @@
1
+ module ReportsKits
2
+ module Reports
3
+ class ModelSettings
4
+ attr_accessor :model_class, :model_configuration_type, :key
5
+
6
+ def initialize(model_class, model_configuration_type, key)
7
+ self.model_class = model_class
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
+ private
23
+
24
+ def model_configuration
25
+ return unless model_class && model_class.respond_to?(:reports_kit_configuration)
26
+ model_class.reports_kit_configuration
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,10 @@
1
+ module ReportsKits
2
+ module Reports
3
+ class Properties
4
+ def self.generate(context)
5
+ properties = context.instance_eval(&ReportsKits.configuration.properties_method)
6
+ properties.deep_symbolize_keys
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ module ReportsKits
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
@@ -0,0 +1,121 @@
1
+ module ReportsKits
2
+ module Reports
3
+ class Series < AbstractSeries
4
+ VALID_KEYS = [:measure, :dimensions, :contextual_filters, :context_params, :filters, :limit, :context_params, :report_options]
5
+
6
+ attr_accessor :properties, :dimensions, :contextual_filters, :filters, :context_record
7
+
8
+ def initialize(properties, context_record: nil)
9
+ properties = { measure: properties } if properties.is_a?(String)
10
+ properties = properties.deep_symbolize_keys.dup
11
+ measure_properties = properties[:measure]
12
+ properties[:measure] = measure_properties
13
+ properties[:measure] = { key: properties[:measure] } if properties[:measure].is_a?(String)
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
+
16
+ contextual_filter_keys = properties[:contextual_filters] || []
17
+ dimension_hashes = properties[:dimensions] || []
18
+ dimension_hashes = dimension_hashes.values if dimension_hashes.is_a?(Hash) && dimension_hashes.key?(:'0')
19
+ filter_hashes = properties[:filters] || []
20
+ filter_hashes = filter_hashes.values if filter_hashes.is_a?(Hash) && filter_hashes.key?(:'0')
21
+
22
+ self.properties = properties
23
+ self.context_record = context_record
24
+ self.dimensions = dimension_hashes.map { |dimension_hash| DimensionWithSeries.new(dimension: Dimension.new(dimension_hash), series: self) }
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, model_class) }
27
+ end
28
+
29
+ def key
30
+ properties[:measure][:key].underscore
31
+ end
32
+
33
+ def label
34
+ properties[:measure][:name].presence || key.pluralize.titleize
35
+ end
36
+
37
+ def limit
38
+ properties[:limit]
39
+ end
40
+
41
+ def edit_relation_method
42
+ ReportsKits.configuration.custom_method(properties[:report_options].try(:[], :edit_relation_method))
43
+ end
44
+
45
+ def relation_name
46
+ key.tableize
47
+ end
48
+
49
+ def aggregate_function
50
+ aggregation_expression || [:count, model_class.primary_key]
51
+ end
52
+
53
+ def aggregation_expression
54
+ return unless aggregation_config
55
+ expression = aggregation_config[:expression]
56
+ if expression.is_a?(Array)
57
+ expression
58
+ else
59
+ raise ArgumentError.new("The '#{aggregation_key}' aggregation on the #{model_class} model isn't valid")
60
+ end
61
+ end
62
+
63
+ def aggregation_key
64
+ properties[:measure][:aggregation]
65
+ end
66
+
67
+ def aggregation_config
68
+ @aggregation_config ||= begin
69
+ return unless aggregation_key
70
+ raise ArgumentError.new("A '#{aggregation_key}' aggregation on the #{model_class} model hasn't been configured") unless model_class.respond_to?(:reports_kit_configuration)
71
+ config = model_class.reports_kit_configuration.aggregations.find { |aggregation| aggregation[:key] == aggregation_key }
72
+ raise ArgumentError.new("A '#{aggregation_key}' aggregation on the #{model_class} model hasn't been configured") unless config
73
+ config
74
+ end
75
+ end
76
+
77
+ def base_relation
78
+ return context_record.public_send(relation_name) if context_record
79
+ model_class
80
+ end
81
+
82
+ def model_class
83
+ if context_record
84
+ reflection = context_record.class.reflect_on_association(key.to_sym) ||
85
+ context_record.class.reflect_on_association(key.pluralize.to_sym)
86
+ return reflection.klass if reflection
87
+ end
88
+ key.camelize.constantize
89
+ end
90
+
91
+ def filtered_relation
92
+ relation = base_relation
93
+ filters.each do |filter|
94
+ relation = filter.apply(relation)
95
+ end
96
+ contextual_filters.each do |filter|
97
+ relation = filter.apply(relation, properties[:context_params])
98
+ end
99
+ relation
100
+ end
101
+
102
+ def has_two_dimensions?
103
+ dimensions.length == 2
104
+ end
105
+
106
+ def self.new_from_properties!(properties, context_record:)
107
+ series_hashes = properties[:series].presence || properties.slice(*Series::VALID_KEYS)
108
+ series_hashes = [series_hashes] if series_hashes.is_a?(Hash)
109
+ raise ArgumentError.new('At least one series must be configured') if series_hashes.blank?
110
+
111
+ series_hashes.map do |series_hash|
112
+ if series_hash[:composite_operator].present?
113
+ CompositeSeries.new(series_hash, context_record: context_record)
114
+ else
115
+ new(series_hash, context_record: context_record)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,65 @@
1
+ require 'csv'
2
+ require 'spreadsheet'
3
+
4
+ module ReportsKits
5
+ class ReportsController < ReportsKits::BaseController
6
+ before_action :modify_context_params
7
+
8
+ VALID_PARAMS_PROPERTIES_KEYS = [:ui_filters]
9
+
10
+ def index
11
+ respond_to do |format|
12
+ format.json do
13
+ render json: { data: report_data }
14
+ end
15
+ format.csv do
16
+ properties[:format] = 'csv'
17
+ csv = CSV.generate do |csv|
18
+ report_data[:table_data].each do |row|
19
+ csv << row
20
+ end
21
+ end
22
+ send_data csv, filename: "#{report_filename}.csv"
23
+ end
24
+ format.xls do
25
+ properties[:format] = 'csv'
26
+ send_data xls_string, filename: "#{report_filename}.xls", type: 'application/vnd.ms-excel'
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def report_filename
34
+ report_filename_method = ReportsKits.configuration.report_filename_method
35
+ return 'Report' unless report_filename_method
36
+ instance_eval(&report_filename_method)
37
+ end
38
+
39
+ def report_data
40
+ Reports::Data::Generate.new(properties, context_record: context_record, context_params: context_params).perform
41
+ end
42
+
43
+ def properties
44
+ @properties ||= begin
45
+ properties = Reports::Properties.generate(self)
46
+ properties.merge(params_properties).deep_symbolize_keys
47
+ end
48
+ end
49
+
50
+ def params_properties
51
+ @params_properties ||= ActiveSupport::JSON.decode(params[:properties]).with_indifferent_access.slice(*VALID_PARAMS_PROPERTIES_KEYS)
52
+ end
53
+
54
+ def xls_string
55
+ spreadsheet = Spreadsheet::Workbook.new
56
+ sheet = spreadsheet.create_worksheet
57
+ report_data[:table_data].each_with_index do |row, index|
58
+ sheet.update_row(index, *row)
59
+ end
60
+ io = StringIO.new
61
+ spreadsheet.write(io)
62
+ io.string
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,11 @@
1
+ module ReportsKits
2
+ class Utils
3
+ def self.string_to_class_method(string, string_identifer)
4
+ class_name, method_name = string.split('.')
5
+ raise ArgumentError.new("The #{string_identifer} value should be a class method with a format of MyClass.my_method") unless class_name && method_name
6
+ klass = class_name.constantize
7
+ raise ArgumentError.new("The #{string_identifer} class (#{class_name}) does not respond to a method named \"#{method_name}\"") unless klass.respond_to?(method_name)
8
+ [klass, method_name]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module ReportsKits
2
+ Value = Struct.new(:raw, :formatted)
3
+ end
@@ -0,0 +1,3 @@
1
+ module ReportsKits
2
+ VERSION = '0.7.7'
3
+ end
@@ -0,0 +1,79 @@
1
+ require 'rails/all'
2
+
3
+ require 'reports_kits/normalized_params'
4
+ require 'reports_kits/base_controller'
5
+ require 'reports_kits/cache'
6
+ require 'reports_kits/configuration'
7
+ require 'reports_kits/engine'
8
+ require 'reports_kits/entity'
9
+ require 'reports_kits/filters_controller'
10
+ require 'reports_kits/form_builder'
11
+ require 'reports_kits/helper'
12
+ require 'reports_kits/model'
13
+ require 'reports_kits/model_configuration'
14
+ require 'reports_kits/order'
15
+ require 'reports_kits/relative_time'
16
+ require 'reports_kits/report_builder'
17
+ require 'reports_kits/reports_controller'
18
+ require 'reports_kits/utils'
19
+ require 'reports_kits/value'
20
+ require 'reports_kits/version'
21
+
22
+ require 'reports_kits/reports/adapters/mysql'
23
+ require 'reports_kits/reports/adapters/postgresql'
24
+
25
+ require 'reports_kits/reports/data/add_table_aggregations'
26
+ require 'reports_kits/reports/data/aggregate_composite'
27
+ require 'reports_kits/reports/data/aggregate_one_dimension'
28
+ require 'reports_kits/reports/data/aggregate_two_dimensions'
29
+ require 'reports_kits/reports/data/chart_data_for_data_method'
30
+ require 'reports_kits/reports/data/chart_options'
31
+ require 'reports_kits/reports/data/format_one_dimension'
32
+ require 'reports_kits/reports/data/format_table'
33
+ require 'reports_kits/reports/data/format_two_dimensions'
34
+ require 'reports_kits/reports/data/generate'
35
+ require 'reports_kits/reports/data/generate_for_properties'
36
+ require 'reports_kits/reports/data/normalize_properties'
37
+ require 'reports_kits/reports/data/populate_one_dimension'
38
+ require 'reports_kits/reports/data/populate_two_dimensions'
39
+ require 'reports_kits/reports/data/utils'
40
+
41
+ require 'reports_kits/reports/filter_types/base'
42
+ require 'reports_kits/reports/filter_types/boolean'
43
+ require 'reports_kits/reports/filter_types/datetime'
44
+ require 'reports_kits/reports/filter_types/number'
45
+ require 'reports_kits/reports/filter_types/records'
46
+ require 'reports_kits/reports/filter_types/string'
47
+
48
+ require 'reports_kits/reports/abstract_series'
49
+ require 'reports_kits/reports/composite_series'
50
+ require 'reports_kits/reports/contextual_filter'
51
+ require 'reports_kits/reports/dimension'
52
+ require 'reports_kits/reports/dimension_with_series'
53
+ require 'reports_kits/reports/filter'
54
+ require 'reports_kits/reports/filter_with_series'
55
+ require 'reports_kits/reports/generate_autocomplete_results'
56
+ require 'reports_kits/reports/generate_autocomplete_method_results'
57
+ require 'reports_kits/reports/inferrable_configuration'
58
+ require 'reports_kits/reports/model_settings'
59
+ require 'reports_kits/reports/properties'
60
+ require 'reports_kits/reports/properties_to_filter'
61
+ require 'reports_kits/reports/series'
62
+
63
+ class ReportsKits
64
+ def self.configure
65
+ yield(configuration)
66
+ end
67
+
68
+ def self.configuration
69
+ @configuration ||= Configuration.new
70
+ end
71
+
72
+ def self.parse_date_range(string)
73
+ ReportsKits::Reports::Data::Utils.parse_date_range(string)
74
+ end
75
+
76
+ def self.format_date_range(string)
77
+ ReportsKits::Reports::Data::Utils.format_date_range(string)
78
+ end
79
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../lib/reports_kits/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.authors = ["aipanhara"]
5
+ s.email = ["titpanhara@gmail.com"]
6
+ s.summary = 'Beautiful, interactive charts for Ruby on Rails'
7
+ s.description = 'ReportsKits lets you easily create beautiful charts with customizable, interactive filters.'
8
+ s.homepage = 'https://github.com/Panhara28/reports_kits'
9
+ s.name = 'reports_kits'
10
+ s.require_paths = ["lib"]
11
+ s.files = `git ls-files`.split($\)
12
+ s.version = ReportsKits::VERSION
13
+ s.license = 'MIT'
14
+ s.add_runtime_dependency 'rails', '~> 5'
15
+ s.add_runtime_dependency 'spreadsheet', '~> 1.1'
16
+
17
+ s. add_development_dependency 'appraisal', '~> 0'
18
+ s.add_development_dependency 'rspec', '~> 3'
19
+ s.add_development_dependency 'database_cleaner', '~> 1'
20
+ s.add_development_dependency 'factory_girl', '~> 4'
21
+ s.add_development_dependency 'groupdate', '~> 3'
22
+ s.add_development_dependency 'pg', '~> 0.15'
23
+ s.add_development_dependency 'pry', '~> 0'
24
+ s.add_development_dependency 'pry-byebug', '~> 1'
25
+ s.add_development_dependency 'timecop', '~> 0'
26
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :issue do
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :issues_label do
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :label do
3
+ end
4
+ 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
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :repo do
3
+ sequence(:full_name) { |i| "foo/bar#{i}" }
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ FactoryGirl.define do
2
+ factory :tag do
3
+ end
4
+ end