reports_kits 0.7.5 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b35a0852529dcce0c76158adc7d87f94051454ac3ded4c714044247e7d38333
4
- data.tar.gz: cda1ecd4c9cd98a670d6b8db57a19eabddff6505abba198e5b28509de5025a99
3
+ metadata.gz: 6f32c4fd9b14483e53d38af3afb1395cc7260277689706c011e11247a6fc8f03
4
+ data.tar.gz: 2b4a6674475973dfd35c2f8619f677b88c8efaebbe094cb81f6c484859188803
5
5
  SHA512:
6
- metadata.gz: f7e2b0725c3ececc97986ecde769610a7fb779810c4fdbe00316f6ece87e941c6c700f7aea088fda4024220ec50909d87ed66fb6bc706d24e4011847ee63ce4e
7
- data.tar.gz: 7bb2251c503ed97d90a4b3c795b47644d7977e439208c2e8d69d58e8aeec2246f72e500102689392c4151e993da5a79c6f443dda8d0be05d741e4b7d728ee3a2
6
+ metadata.gz: 3c5c37ab2de7fe6da1787565b9bf7ee635da322ccfd3769b26470262c90b092c4c705be63c02b2c0ce49beaebf749332ffd3cecd064d901ed4aff601f4515c43
7
+ data.tar.gz: 02c85dc627f4dd78102ef7b2f8cb4ac1ce3aafee7e34161d634fb1f32ae0c5bc033e3274668f9b1f75a4f29302770b458a15297e67cbc2b078c7fa81080a8d89
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ *.gem
4
+ log/*.log
5
+ .bundle/
6
+ pkg/
data/.rubocop.yml ADDED
@@ -0,0 +1,85 @@
1
+ # inherits from https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - spec/support/schema.rb
6
+ - bin/**/*
7
+ - tmp/**/*
8
+ - vendor/**/*
9
+ - .bundle/**/*
10
+ Rails:
11
+ Enabled: true
12
+ DisplayCopNames: true
13
+ DisplayStyleGuide: true
14
+
15
+ Documentation:
16
+ Enabled: false
17
+
18
+ Metrics/AbcSize:
19
+ Enabled: true
20
+ Max: 40
21
+ Metrics/BlockLength:
22
+ Exclude:
23
+ - spec/**/*
24
+ Metrics/CyclomaticComplexity:
25
+ Enabled: true
26
+ Max: 12
27
+ Metrics/LineLength:
28
+ Enabled: true
29
+ Max: 140
30
+ Metrics/PerceivedComplexity:
31
+ Enabled: true
32
+ Max: 12
33
+ Metrics/ClassLength:
34
+ Enabled: true
35
+ CountComments: false
36
+ Max: 200
37
+ Metrics/ModuleLength:
38
+ CountComments: false
39
+ Max: 200
40
+ Enabled: true
41
+ Metrics/MethodLength:
42
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
43
+ Enabled: true
44
+ CountComments: false
45
+ Max: 50
46
+ Metrics/ParameterLists:
47
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
48
+ Enabled: true
49
+ Max: 5
50
+ CountKeywordArgs: true
51
+
52
+ Lint/AssignmentInCondition:
53
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
54
+ Enabled: true
55
+ AllowSafeAssignment: true
56
+ Lint/UnusedBlockArgument:
57
+ Enabled: false
58
+
59
+ Style/AccessorMethodName:
60
+ Enabled: true
61
+ Style/AlignHash:
62
+ EnforcedColonStyle: key
63
+ EnforcedHashRocketStyle: key
64
+ Style/AlignParameters:
65
+ EnforcedStyle: with_fixed_indentation
66
+ Style/Alias:
67
+ StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
68
+ EnforcedStyle: prefer_alias_method
69
+ Style/BracesAroundHashParameters:
70
+ Exclude:
71
+ - spec/**/*
72
+ Style/CaseIndentation:
73
+ EnforcedStyle: case
74
+ SupportedStyles:
75
+ - case
76
+ - end
77
+ IndentOneStep: false
78
+ Style/IndentHash:
79
+ EnforcedStyle: consistent
80
+ Style/RaiseArgs:
81
+ Enabled: false
82
+ Style/SignalException:
83
+ Enabled: false
84
+ Style/SpecialGlobalVars:
85
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ cache: bundler
2
+
3
+ language: ruby
4
+
5
+ services:
6
+ - mysql
7
+ - postgresql
8
+
9
+ rvm:
10
+ - '2.2.7'
11
+ - '2.3.4'
12
+ - '2.4.1'
13
+
14
+ before_install: gem update bundler
15
+ before_script:
16
+ - psql -c 'CREATE DATABASE reports_kit_test;' -U postgres
17
+ - mysql -e 'CREATE DATABASE IF NOT EXISTS reports_kit_test;'
18
+ - mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
19
+ - bundle exec appraisal install
20
+
21
+ script: bundle exec appraisal rspec
data/Appraisals ADDED
@@ -0,0 +1,27 @@
1
+ appraise 'rails_4_mysql' do
2
+ gem 'mysql2'
3
+ gem 'rails', '4.2.10'
4
+ end
5
+
6
+ appraise 'rails_4_postgresql' do
7
+ gem 'pg'
8
+ gem 'rails', '4.2.10'
9
+ end
10
+
11
+ appraise 'rails_5_mysql' do
12
+ gem 'mysql2'
13
+ gem 'rails', '5.1.3'
14
+ end
15
+
16
+ appraise 'rails_5_postgresql' do
17
+ gem 'pg'
18
+ gem 'rails', '5.1.3'
19
+ end
20
+
21
+ # Rails 5.1.4 introduced a bug that generates invalid SQL when using distinct, group, limit and count. This should be resolved in 5.1.5,
22
+ # but we'll need to specifically test against 5.1.4 to prevent this bug from impacting ReportsKit when Rails 5.1.4 is being used.
23
+ # See https://github.com/tombenner/reports_kit/issues/6
24
+ appraise 'rails_5.1.4_postgresql' do
25
+ gem 'pg'
26
+ gem 'rails', '5.1.4'
27
+ end
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Tom Benner
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ ReportsKit
2
+ =====
3
+ [![Build Status](https://travis-ci.org/tombenner/reports_kit.svg?branch=master)](https://travis-ci.org/tombenner/reports_kit)
4
+
5
+ ReportsKit lets you easily create beautiful, interactive charts and tables.
6
+
7
+ For examples and documentation, see [reportskit.co](https://www.reportskit.co/).
8
+
9
+ [<img src="docs/images/demo.gif?raw=true" width="700" />](docs/images/demo.gif?raw=true)
10
+
11
+ Resources
12
+ ---------
13
+
14
+ * [Documentation](https://www.reportskit.co/)
15
+ * [Getting Started](https://www.reportskit.co/categories/getting_started)
16
+ * [How It Works](https://www.reportskit.co/subcategories/how_it_works)
17
+
18
+ Documentation
19
+ -------------
20
+
21
+ The documentation is hosted at [reportskit.co](https://www.reportskit.co/), and it's generated using [tombenner/reports_kit_docs](https://github.com/tombenner/reports_kit_docs). If you'd like to improve the documentation, feel free to open a PR!
22
+
23
+ Testing
24
+ -------
25
+
26
+ ReportsKit is tested against PostgreSQL and MySQL. If you'd like to submit a PR, please be sure to use [Appraisal](https://github.com/thoughtbot/appraisal) to test your changes in both contexts:
27
+
28
+ ```bash
29
+ appraisal rspec
30
+ ```
31
+
32
+ License
33
+ -------
34
+
35
+ ReportsKit is released under the MIT License. Please see the MIT-LICENSE file for details.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
@@ -0,0 +1,14 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require ./vendor/moment
14
+ //= require_tree .
@@ -0,0 +1,9 @@
1
+ window.ReportsKits = {};
2
+
3
+ $(document).ready(function() {
4
+ $('.reports_kit_report').each(function(index, el) {
5
+ var el = $(el)
6
+ var reportClass = el.data('report-class');
7
+ new ReportsKits[reportClass]().render({ 'el': el });
8
+ });
9
+ });
@@ -0,0 +1,73 @@
1
+ ReportsKits.Chart = (function(options) {
2
+ var self = this;
3
+
4
+ self.initialize = function(options) {
5
+ self.options = options;
6
+ self.report = options.report;
7
+ self.el = self.report.el;
8
+
9
+ self.defaultEmptyStateText = 'No data was found';
10
+ self.emptyStateEl = $('<div>' + self.defaultEmptyStateText + '</div>').appendTo(self.report.visualizationEl).hide();
11
+ self.loadingIndicatorEl = $('<div class="loading_indicator"></div>').appendTo(self.report.visualizationEl).hide();
12
+ self.canvas = $('<canvas />').appendTo(self.report.visualizationEl);
13
+ };
14
+
15
+ self.render = function() {
16
+ var path = self.el.data('path');
17
+ var separator = path.indexOf('?') === -1 ? '?' : '&';
18
+ path += separator + 'properties=' + encodeURIComponent(JSON.stringify(self.report.properties()));
19
+ self.loadingIndicatorEl.fadeIn(1000);
20
+ if (self.canvas.is(':visible')) {
21
+ self.canvas.fadeTo(300, 0.1);
22
+ }
23
+ $.getJSON(path, function(response) {
24
+ var data = response.data;
25
+ var chartData = data.chart_data;
26
+ var isEmptyState = chartData.datasets.length === 0 ||
27
+ (chartData.datasets.length === 1 && chartData.datasets[0].data.length === 0);
28
+ var emptyStateText = (data.report_options && data.report_options.empty_state_text) || self.defaultEmptyStateText;
29
+ var options = chartData.options;
30
+ options = self.addAdditionalOptions(options, data.report_options);
31
+
32
+ self.loadingIndicatorEl.stop(true, true).hide();
33
+ self.emptyStateEl.html(emptyStateText).toggle(isEmptyState);
34
+ if (isEmptyState) {
35
+ self.canvas.hide();
36
+ return;
37
+ }
38
+ self.canvas.show().fadeTo(300, 1);
39
+
40
+ var args = {
41
+ type: data.type,
42
+ data: chartData,
43
+ options: options
44
+ };
45
+
46
+ if (self.chart) {
47
+ self.chart.data.datasets = chartData.datasets;
48
+ self.chart.data.labels = chartData.labels;
49
+ self.chart.update();
50
+ } else {
51
+ self.chart = new Chart(self.canvas, args);
52
+ }
53
+ });
54
+ };
55
+
56
+ self.addAdditionalOptions = function(options, reportOptions) {
57
+ var additionalOptions = {};
58
+ var maxItems = reportOptions && reportOptions.legend && reportOptions.legend.max_items;
59
+ if (maxItems) {
60
+ options.legend = options.legend || {};
61
+ options.legend.labels = options.legend.labels || {};
62
+ options.legend.labels.filter = options.legend.labels.filter || function(item) {
63
+ var index = (typeof item.datasetIndex === 'undefined') ? item.index : item.datasetIndex;
64
+ return index < maxItems;
65
+ };
66
+ }
67
+ return options;
68
+ };
69
+
70
+ self.initialize(options);
71
+
72
+ return self;
73
+ });
@@ -0,0 +1,135 @@
1
+ ReportsKits.Report = (function() {
2
+ var self = this;
3
+
4
+ self.render = function(options) {
5
+ self.el = options.el;
6
+ self.visualizationEl = self.el.find('.reports_kit_visualization');
7
+
8
+ self.defaultProperties = self.el.data('properties');
9
+ self.form = self.el.find('.reports_kit_report_form');
10
+
11
+ self.initializeElements();
12
+ self.initializeEvents();
13
+ self.initializeVisualization();
14
+ self.renderVisualization();
15
+ };
16
+
17
+ self.initializeVisualization = function() {
18
+ if (self.defaultProperties.format == 'table') {
19
+ self.visualization = new ReportsKits.Table({ report: self });
20
+ } else {
21
+ self.visualization = new ReportsKits.Chart({ report: self });
22
+ }
23
+ };
24
+
25
+ self.initializeElements = function() {
26
+ self.exportButtons = self.el.find('[data-role=reports_kit_export_button]');
27
+ self.initializeAutocompletes();
28
+ self.initializeDateRangePickers();
29
+ };
30
+
31
+ self.initializeAutocompletes = function() {
32
+ self.form.find('.select2').each(function(index, el) {
33
+ el = $(el);
34
+ var path = el.data('path');
35
+ var elParams = el.data('params');
36
+ el.select2({
37
+ theme: 'bootstrap',
38
+ minimumResultsForSearch: 10,
39
+ ajax: {
40
+ url: path,
41
+ dataType: 'json',
42
+ delay: 250,
43
+ data: function(params) {
44
+ var data = {
45
+ q: params.term,
46
+ page: params.page
47
+ };
48
+ data = $.extend(data, elParams);
49
+ return data;
50
+ },
51
+ processResults: function(data, params) {
52
+ params.page = params.page || 1;
53
+ return { results: data.data }
54
+ },
55
+ cache: true
56
+ }
57
+ });
58
+ });
59
+ };
60
+
61
+ self.initializeDateRangePickers = function() {
62
+ self.form.find('.date_range_picker').daterangepicker({
63
+ opens: 'left',
64
+ drops: 'down',
65
+ showDropdowns: false,
66
+ showWeekNumbers: false,
67
+ timePicker: false,
68
+ buttonClasses: ['btn', 'btn-sm'],
69
+ applyClass: 'btn-primary btn-daterange-submit',
70
+ cancelClass: 'btn-default',
71
+ maxDate: moment(),
72
+ locale: {
73
+ format: 'MMM D, YYYY'
74
+ },
75
+ ranges: {
76
+ 'Last 30 Days': [moment().subtract(30, 'days'), moment()],
77
+ 'Last 2 Months': [moment().subtract(2, 'months'), moment()],
78
+ 'Last 3 Months': [moment().subtract(3, 'months'), moment()],
79
+ 'Last 4 Months': [moment().subtract(4, 'months'), moment()],
80
+ 'Last 6 Months': [moment().subtract(6, 'months'), moment()],
81
+ 'Last 12 Months': [moment().subtract(12, 'months'), moment()],
82
+ 'Year To Date': [moment().startOf('year'), moment()]
83
+ }
84
+ });
85
+ };
86
+
87
+ self.initializeEvents = function() {
88
+ self.form.find('select,input').on('change', function() {
89
+ self.renderVisualization();
90
+ })
91
+ self.form.on('submit', function() {
92
+ self.renderVisualization();
93
+ return false;
94
+ })
95
+ self.exportButtons.on('click', self.onClickExportButton);
96
+ };
97
+
98
+ self.properties = function() {
99
+ var filterKeysValues = {};
100
+ self.form.find('select,:text').each(function(index, el) {
101
+ var filter = $(el);
102
+ var key = filter.attr('name');
103
+ filterKeysValues[key] = filter.val();
104
+ });
105
+ self.form.find(':checkbox').each(function(index, el) {
106
+ var filter = $(el);
107
+ var key = filter.attr('name');
108
+ filterKeysValues[key] = filter.prop('checked');
109
+ });
110
+ var properties = $.extend({}, self.defaultProperties);
111
+
112
+ properties.ui_filters = {};
113
+ Object.keys(filterKeysValues).forEach(function(key, index) {
114
+ var value = filterKeysValues[key];
115
+ properties.ui_filters[key] = value;
116
+ });
117
+
118
+ return properties;
119
+ };
120
+
121
+ self.onClickExportButton = function(event) {
122
+ var el = $(event.target);
123
+ var path = el.data('path');
124
+ var separator = path.indexOf('?') === -1 ? '?' : '&';
125
+ path += separator + 'properties=' + encodeURIComponent(JSON.stringify(self.properties()));
126
+ window.open(path, '_blank');
127
+ return false;
128
+ };
129
+
130
+ self.renderVisualization = function() {
131
+ self.visualization.render();
132
+ };
133
+
134
+ return self;
135
+ });
@@ -0,0 +1,87 @@
1
+ ReportsKits.Table = (function(options) {
2
+ var self = this;
3
+
4
+ self.initialize = function(options) {
5
+ self.options = options;
6
+ self.report = options.report;
7
+ self.el = self.report.el;
8
+
9
+ self.defaultEmptyStateText = 'No data was found';
10
+ self.emptyStateEl = $('<div>' + self.defaultEmptyStateText + '</div>').appendTo(self.report.visualizationEl).hide();
11
+ self.loadingIndicatorEl = $('<div class="loading_indicator"></div>').appendTo(self.report.visualizationEl).hide();
12
+ self.table = $('<table />', { 'class': 'table table-striped table-hover' }).appendTo(self.report.visualizationEl);
13
+ };
14
+
15
+ self.render = function() {
16
+ var path = self.el.data('path');
17
+ var separator = path.indexOf('?') === -1 ? '?' : '&';
18
+ path += separator + 'properties=' + encodeURIComponent(JSON.stringify(self.report.properties()));
19
+ self.loadingIndicatorEl.fadeIn(1000);
20
+ if (self.table.is(':visible')) {
21
+ self.table.fadeTo(300, 0.1);
22
+ }
23
+ $.getJSON(path, function(response) {
24
+ var data = response.data;
25
+ var tableData = data.table_data;
26
+ var reportOptions = data.report_options || {};
27
+ // If the data only includes column headers, then it we have an empty state.
28
+ var isEmptyState = tableData.length <= 1;
29
+ var emptyStateText = reportOptions.empty_state_text || self.defaultEmptyStateText;
30
+ self.emptyStateEl.html(emptyStateText);
31
+
32
+ self.loadingIndicatorEl.stop(true, true).hide();
33
+ self.emptyStateEl.toggle(isEmptyState);
34
+ if (isEmptyState) {
35
+ self.table.hide();
36
+ return;
37
+ }
38
+ self.table.show().fadeTo(300, 1);
39
+
40
+ var rowsCount = tableData.length;
41
+
42
+ var hasHead = typeof reportOptions.head_rows_count !== 'undefined';
43
+ var hasFoot = typeof reportOptions.foot_rows_count !== 'undefined';
44
+ var headRowStartIndex = hasHead ? 0 : 0;
45
+ var headRowEndIndex = hasHead ? reportOptions.head_rows_count - 1 : 0;
46
+ var footRowStartIndex = hasFoot ? rowsCount - reportOptions.foot_rows_count : null;
47
+ var footRowEndIndex = hasFoot ? rowsCount - 1 : null;
48
+
49
+ var html = '';
50
+ for(var i = 0; i < rowsCount; i++) {
51
+ if (i === headRowStartIndex) {
52
+ html += '<thead><tr>';
53
+ } else if (i === (headRowEndIndex + 1)) {
54
+ html += '<tbody><tr>';
55
+ } else if (i === footRowStartIndex) {
56
+ html += '<tfoot><tr>';
57
+ } else {
58
+ html += '<tr>';
59
+ }
60
+
61
+ for(var j = 0; j < tableData[i].length; j++) {
62
+ if (i == 0 || j == 0) {
63
+ html += '<th>' + (tableData[i][j] || '') + '</th>';
64
+ } else {
65
+ html += '<td>' + ((tableData[i][j] === null) ? '' : tableData[i][j]) + '</td>';
66
+ }
67
+ }
68
+
69
+ if (i === headRowEndIndex) {
70
+ html += '</tr></thead>';
71
+ } else if (i === (footRowStartIndex - 1)) {
72
+ html += '</tr></tbody>';
73
+ } else if (i === footRowEndIndex) {
74
+ html += '</tfoot></tbody>';
75
+ } else {
76
+ html += '</tr>';
77
+ }
78
+ }
79
+ self.table.html(html);
80
+ self.table.tablesorter({ sortInitialOrder: 'desc' });
81
+ });
82
+ };
83
+
84
+ self.initialize(options);
85
+
86
+ return self;
87
+ });