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.
- checksums.yaml +4 -4
- data/.gitignore +6 -0
- data/.rubocop.yml +85 -0
- data/.travis.yml +21 -0
- data/Appraisals +27 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/app/assets/javascripts/reports_kits/application.js +14 -0
- data/app/assets/javascripts/reports_kits/lib/_init.js +9 -0
- data/app/assets/javascripts/reports_kits/lib/chart.js +73 -0
- data/app/assets/javascripts/reports_kits/lib/report.js +135 -0
- data/app/assets/javascripts/reports_kits/lib/table.js +87 -0
- data/app/assets/javascripts/reports_kits/vendor/chart.js +12269 -0
- data/app/assets/javascripts/reports_kits/vendor/daterangepicker.js +1627 -0
- data/app/assets/javascripts/reports_kits/vendor/jquery.tablesorter.min.js +4 -0
- data/app/assets/javascripts/reports_kits/vendor/moment.js +4040 -0
- data/app/assets/javascripts/reports_kits/vendor/select2.full.js +6436 -0
- data/app/assets/stylesheets/reports_kits/application.css.scss +3 -0
- data/app/assets/stylesheets/reports_kits/reports.css.sass +33 -0
- data/app/assets/stylesheets/reports_kits/select2_overrides.css.sass +7 -0
- data/app/assets/stylesheets/reports_kits/vendor/daterangepicker.css +269 -0
- data/app/assets/stylesheets/reports_kits/vendor/select2-bootstrap.css +721 -0
- data/app/assets/stylesheets/reports_kits/vendor/select2.css +484 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/routes.rb +10 -0
- data/docs/images/demo.gif +0 -0
- data/docs/images/users_by_created_at.png +0 -0
- data/gemfiles/mysql.gemfile +7 -0
- data/gemfiles/mysql.gemfile.lock +167 -0
- data/gemfiles/postgresql.gemfile +7 -0
- data/gemfiles/postgresql.gemfile.lock +165 -0
- data/gemfiles/postgresql_rails_5.1.4.gemfile +8 -0
- data/gemfiles/postgresql_rails_5.1.4.gemfile.lock +168 -0
- data/gemfiles/rails_4_mysql.gemfile +8 -0
- data/gemfiles/rails_4_mysql.gemfile.lock +165 -0
- data/gemfiles/rails_4_postgresql.gemfile +8 -0
- data/gemfiles/rails_4_postgresql.gemfile.lock +163 -0
- data/gemfiles/rails_5.1.4_postgresql.gemfile +8 -0
- data/gemfiles/rails_5.1.4_postgresql.gemfile.lock +169 -0
- data/gemfiles/rails_5_mysql.gemfile +8 -0
- data/gemfiles/rails_5_mysql.gemfile.lock +171 -0
- data/gemfiles/rails_5_postgresql.gemfile +8 -0
- data/gemfiles/rails_5_postgresql.gemfile.lock +169 -0
- data/lib/reports_kits/base_controller.rb +17 -0
- data/lib/reports_kits/cache.rb +37 -0
- data/lib/reports_kits/configuration.rb +50 -0
- data/lib/reports_kits/engine.rb +21 -0
- data/lib/reports_kits/entity.rb +3 -0
- data/lib/reports_kits/filters_controller.rb +11 -0
- data/lib/reports_kits/form_builder.rb +66 -0
- data/lib/reports_kits/helper.rb +24 -0
- data/lib/reports_kits/model.rb +16 -0
- data/lib/reports_kits/model_configuration.rb +28 -0
- data/lib/reports_kits/normalized_params.rb +16 -0
- data/lib/reports_kits/order.rb +33 -0
- data/lib/reports_kits/relative_time.rb +42 -0
- data/lib/reports_kits/report_builder.rb +88 -0
- data/lib/reports_kits/reports/abstract_series.rb +9 -0
- data/lib/reports_kits/reports/adapters/mysql.rb +26 -0
- data/lib/reports_kits/reports/adapters/postgresql.rb +26 -0
- data/lib/reports_kits/reports/composite_series.rb +48 -0
- data/lib/reports_kits/reports/contextual_filter.rb +19 -0
- data/lib/reports_kits/reports/data/add_table_aggregations.rb +105 -0
- data/lib/reports_kits/reports/data/aggregate_composite.rb +97 -0
- data/lib/reports_kits/reports/data/aggregate_one_dimension.rb +39 -0
- data/lib/reports_kits/reports/data/aggregate_two_dimensions.rb +39 -0
- data/lib/reports_kits/reports/data/chart_data_for_data_method.rb +62 -0
- data/lib/reports_kits/reports/data/chart_options.rb +155 -0
- data/lib/reports_kits/reports/data/format_one_dimension.rb +140 -0
- data/lib/reports_kits/reports/data/format_table.rb +63 -0
- data/lib/reports_kits/reports/data/format_two_dimensions.rb +143 -0
- data/lib/reports_kits/reports/data/generate.rb +156 -0
- data/lib/reports_kits/reports/data/generate_for_properties.rb +97 -0
- data/lib/reports_kits/reports/data/normalize_properties.rb +62 -0
- data/lib/reports_kits/reports/data/populate_one_dimension.rb +54 -0
- data/lib/reports_kits/reports/data/populate_two_dimensions.rb +104 -0
- data/lib/reports_kits/reports/data/utils.rb +178 -0
- data/lib/reports_kits/reports/dimension.rb +27 -0
- data/lib/reports_kits/reports/dimension_with_series.rb +144 -0
- data/lib/reports_kits/reports/filter.rb +29 -0
- data/lib/reports_kits/reports/filter_types/base.rb +48 -0
- data/lib/reports_kits/reports/filter_types/boolean.rb +47 -0
- data/lib/reports_kits/reports/filter_types/datetime.rb +51 -0
- data/lib/reports_kits/reports/filter_types/number.rb +30 -0
- data/lib/reports_kits/reports/filter_types/records.rb +26 -0
- data/lib/reports_kits/reports/filter_types/string.rb +38 -0
- data/lib/reports_kits/reports/filter_with_series.rb +97 -0
- data/lib/reports_kits/reports/generate_autocomplete_method_results.rb +29 -0
- data/lib/reports_kits/reports/generate_autocomplete_results.rb +57 -0
- data/lib/reports_kits/reports/inferrable_configuration.rb +116 -0
- data/lib/reports_kits/reports/model_settings.rb +30 -0
- data/lib/reports_kits/reports/properties.rb +10 -0
- data/lib/reports_kits/reports/properties_to_filter.rb +40 -0
- data/lib/reports_kits/reports/series.rb +121 -0
- data/lib/reports_kits/reports_controller.rb +65 -0
- data/lib/reports_kits/utils.rb +11 -0
- data/lib/reports_kits/value.rb +3 -0
- data/lib/reports_kits/version.rb +3 -0
- data/lib/reports_kits.rb +79 -0
- data/reports_kits.gemspec +26 -0
- data/spec/factories/issue_factory.rb +4 -0
- data/spec/factories/issues_label_factory.rb +4 -0
- data/spec/factories/label_factory.rb +4 -0
- data/spec/factories/pro_repo_factory.rb +5 -0
- data/spec/factories/repo_factory.rb +5 -0
- data/spec/factories/tag_factory.rb +4 -0
- data/spec/fixtures/generate_inputs.yml +254 -0
- data/spec/fixtures/generate_outputs.yml +1216 -0
- data/spec/reports_kit/form_builder_spec.rb +26 -0
- data/spec/reports_kit/relative_time_spec.rb +29 -0
- data/spec/reports_kit/reports/data/generate/contextual_filters_spec.rb +60 -0
- data/spec/reports_kit/reports/data/generate_spec.rb +1371 -0
- data/spec/reports_kit/reports/data/normalize_properties_spec.rb +196 -0
- data/spec/reports_kit/reports/dimension_with_series_spec.rb +67 -0
- data/spec/reports_kit/reports/filter_with_series_spec.rb +39 -0
- data/spec/reports_kit/reports/generate_autocomplete_results_spec.rb +69 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/support/config.rb +41 -0
- data/spec/support/example_data_methods.rb +25 -0
- data/spec/support/factory_girl.rb +5 -0
- data/spec/support/helpers.rb +25 -0
- data/spec/support/models/issue.rb +14 -0
- data/spec/support/models/issues_label.rb +4 -0
- data/spec/support/models/label.rb +5 -0
- data/spec/support/models/pro/repo.rb +5 -0
- data/spec/support/models/pro/special_issue.rb +4 -0
- data/spec/support/models/repo.rb +13 -0
- data/spec/support/models/tag.rb +4 -0
- data/spec/support/schema.rb +39 -0
- metadata +134 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f32c4fd9b14483e53d38af3afb1395cc7260277689706c011e11247a6fc8f03
|
4
|
+
data.tar.gz: 2b4a6674475973dfd35c2f8619f677b88c8efaebbe094cb81f6c484859188803
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c5c37ab2de7fe6da1787565b9bf7ee635da322ccfd3769b26470262c90b092c4c705be63c02b2c0ce49beaebf749332ffd3cecd064d901ed4aff601f4515c43
|
7
|
+
data.tar.gz: 02c85dc627f4dd78102ef7b2f8cb4ac1ce3aafee7e34161d634fb1f32ae0c5bc033e3274668f9b1f75a4f29302770b458a15297e67cbc2b078c7fa81080a8d89
|
data/.gitignore
ADDED
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
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,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,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
|
+
});
|