query_report 0.1.2 → 1.0.0
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.
- data/{LICENSE.txt → MIT-LICENSE} +2 -4
- data/README.md +32 -53
- data/Rakefile +50 -0
- data/app/helpers/query_report_filter_helper.rb +22 -0
- data/app/helpers/query_report_helper.rb +31 -0
- data/app/views/query_report/_charts.html.erb +10 -0
- data/app/views/query_report/_search.html.erb +8 -0
- data/app/views/query_report/list.html.erb +19 -38
- data/config/locales/query_report.yml +7 -0
- data/config/routes.rb +2 -0
- data/db/schema.rb +34 -0
- data/lib/query_report.rb +22 -15
- data/lib/query_report/chart/chart_base.rb +60 -0
- data/lib/query_report/chart/chart_column.rb +12 -0
- data/lib/query_report/chart/column_chart.rb +40 -0
- data/lib/query_report/chart/pie_chart.rb +22 -25
- data/lib/query_report/chart/themes.rb +18 -114
- data/lib/query_report/column.rb +29 -18
- data/lib/query_report/config.rb +6 -0
- data/lib/query_report/engine.rb +4 -0
- data/lib/query_report/errors.rb +4 -0
- data/lib/query_report/filter.rb +110 -31
- data/lib/query_report/helper.rb +19 -3
- data/lib/query_report/paginate.rb +13 -0
- data/lib/query_report/record.rb +46 -0
- data/lib/query_report/report.rb +19 -102
- data/lib/query_report/report_pdf.rb +68 -84
- data/lib/query_report/version.rb +1 -1
- data/lib/tasks/query_report_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/javascripts/invoices.js +2 -0
- data/test/dummy/app/assets/javascripts/users.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/invoices.css +4 -0
- data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/test/dummy/app/assets/stylesheets/users.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/invoices_controller.rb +114 -0
- data/test/dummy/app/controllers/users_controller.rb +91 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/invoices_helper.rb +2 -0
- data/test/dummy/app/helpers/users_helper.rb +2 -0
- data/test/dummy/app/models/invoice.rb +3 -0
- data/test/dummy/app/models/pdf_report_template.rb +24 -0
- data/test/dummy/app/models/user.rb +3 -0
- data/test/dummy/app/views/invoices/_form.html.erb +33 -0
- data/test/dummy/app/views/invoices/edit.html.erb +6 -0
- data/test/dummy/app/views/invoices/index.html.erb +29 -0
- data/test/dummy/app/views/invoices/new.html.erb +5 -0
- data/test/dummy/app/views/invoices/show.html.erb +25 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/users/_form.html.erb +33 -0
- data/test/dummy/app/views/users/edit.html.erb +6 -0
- data/test/dummy/app/views/users/index.html.erb +29 -0
- data/test/dummy/app/views/users/new.html.erb +5 -0
- data/test/dummy/app/views/users/show.html.erb +25 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +60 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/query_report.rb +3 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +10 -0
- data/test/dummy/config/routes.rb +64 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20130622120853_create_users.rb +12 -0
- data/test/dummy/db/migrate/20130630132513_create_invoices.rb +12 -0
- data/test/dummy/db/schema.rb +34 -0
- data/test/dummy/db/seed.rb +4 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +30613 -0
- data/test/dummy/log/test.log +28 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/fixtures/invoices.yml +13 -0
- data/test/dummy/test/functional/invoices_controller_test.rb +49 -0
- data/test/dummy/test/unit/helpers/invoices_helper_test.rb +4 -0
- data/test/dummy/test/unit/invoice_test.rb +7 -0
- data/test/dummy/tmp/cache/assets/C8C/B80/sprockets%2F371bf96e99717688ed7313a0c53f4212 +0 -0
- data/test/dummy/tmp/cache/assets/CA9/F20/sprockets%2F00ff4f84806dd8834ab35f800a082640 +0 -0
- data/test/dummy/tmp/cache/assets/CAA/620/sprockets%2F87b209c0c9da28094a8d5581a21262c6 +0 -0
- data/test/dummy/tmp/cache/assets/CB5/B70/sprockets%2Fa769d915e72b1c8c0614793b54d02c86 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/B70/sprockets%2F4050a4e5062ab95c9f32e9b6940821ea +0 -0
- data/test/dummy/tmp/cache/assets/CF0/1D0/sprockets%2F6fc757c2c8329244ca95d6909865bbc2 +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D46/650/sprockets%2Ff56253b5f374fff1a33fbbc9881c9124 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D54/B90/sprockets%2F90719d7bdca76469cd487928f710decb +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D67/B60/sprockets%2F5f1a0d05e77ca8b9a1fc2a47e17a8174 +0 -0
- data/test/dummy/tmp/cache/assets/D7C/990/sprockets%2F302f7d851fcdb17936f8096bfb967cab +0 -0
- data/test/dummy/tmp/cache/assets/D7F/AF0/sprockets%2Fa7deca9af827ab462635389b96c7da39 +0 -0
- data/test/dummy/tmp/cache/assets/DA3/AC0/sprockets%2F797d3e5f21daaf5c046cc6ec4830e95b +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/DFC/6F0/sprockets%2F2c45c36e4d7c7bfaeb826eeba29a09d2 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E0E/8A0/sprockets%2Fbecd48a9cf2ece858e433d7dcf0554f6 +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_5awpjfhldzcfjkeiia3p +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_a7ev5lal7xp2xzjj2n9p +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_c5lzifpf785aic4t3cm8 +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_etmdhvrbbmdadc7oyw8q +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_m0kxxiow6jlfcjulu02t +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_m2ow1xy7c6tw0f4fj2co +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_mitzsa7y0lvka04il6an +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_ujpdek4jfp8flbqp7fi3 +0 -0
- data/test/dummy/tmp/miniprofiler/mp_timers_wbiyljqrnox89js4m0at +0 -0
- data/test/dummy/tmp/miniprofiler/mp_views_127.0.0.1 +1 -0
- data/test/test_helper.rb +15 -0
- metadata +380 -24
- data/.gitignore +0 -18
- data/Gemfile +0 -10
- data/README.rdoc +0 -3
- data/app/views/query_report/_custom_filters.html.erb +0 -7
- data/lib/query_report/chart/basic_chart.rb +0 -41
- data/lib/query_report/chart/custom_chart.rb +0 -55
- data/lib/query_report/row.rb +0 -11
- data/query_report.gemspec +0 -31
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'query_report/chart/themes'
|
|
2
|
+
require 'query_report/chart/chart_base'
|
|
3
|
+
|
|
4
|
+
module QueryReport
|
|
5
|
+
module ColumnChartModule
|
|
6
|
+
def column_chart(title, &block)
|
|
7
|
+
chart = QueryReport::Chart::ColumnChart.new(title, self.filtered_query)
|
|
8
|
+
chart.instance_eval &block if block_given?
|
|
9
|
+
@charts ||= []
|
|
10
|
+
@charts << chart
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module Chart
|
|
15
|
+
class ColumnChart < QueryReport::Chart::ChartBase
|
|
16
|
+
def initialize(title, query, options={})
|
|
17
|
+
super(title, query, options)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def prepare_visualr
|
|
21
|
+
@data_table = GoogleVisualr::DataTable.new
|
|
22
|
+
|
|
23
|
+
##### Adding column header #####
|
|
24
|
+
@data_table.new_column('string', '')
|
|
25
|
+
@columns.each do |col|
|
|
26
|
+
@data_table.new_column(col.type.to_s, col.title)
|
|
27
|
+
end
|
|
28
|
+
##### Adding column header #####
|
|
29
|
+
|
|
30
|
+
@data_table.add_row([''] + @data)
|
|
31
|
+
options = {:title => title, backgroundColor: 'transparent'}.merge(@options)
|
|
32
|
+
GoogleVisualr::Interactive::ColumnChart.new(@data_table, options)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_blob
|
|
36
|
+
super(:bar)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -1,43 +1,40 @@
|
|
|
1
1
|
require 'query_report/chart/themes'
|
|
2
|
+
require 'query_report/chart/chart_base'
|
|
2
3
|
|
|
3
4
|
module QueryReport
|
|
4
|
-
module
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
module PieChartModule
|
|
6
|
+
def pie_chart(title, &block)
|
|
7
|
+
chart = QueryReport::Chart::PieChart.new(title, self.filtered_query)
|
|
8
|
+
chart.instance_eval &block if block_given?
|
|
9
|
+
@charts ||= []
|
|
10
|
+
@charts << chart
|
|
11
|
+
end
|
|
12
|
+
end
|
|
7
13
|
|
|
14
|
+
module Chart
|
|
15
|
+
class PieChart < QueryReport::Chart::ChartBase
|
|
8
16
|
def initialize(title, query, options={})
|
|
9
|
-
|
|
10
|
-
@options = options
|
|
11
|
-
@rows = []
|
|
12
|
-
@query = query
|
|
17
|
+
super(title, query, options)
|
|
13
18
|
end
|
|
14
19
|
|
|
15
|
-
def
|
|
16
|
-
val = block.call(@query)
|
|
17
|
-
@rows << [column_title, val]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def prepare
|
|
20
|
+
def prepare_visualr
|
|
21
21
|
@data_table = GoogleVisualr::DataTable.new
|
|
22
|
+
|
|
23
|
+
##### Adding column header #####
|
|
22
24
|
@data_table.new_column('string', 'Item')
|
|
23
25
|
@data_table.new_column('number', 'Value')
|
|
24
|
-
|
|
25
|
-
opts = {:width => 500, :height => 240, :title => @title, :is3D => true, backgroundColor: 'transparent'}.merge(options)
|
|
26
|
-
GoogleVisualr::Interactive::PieChart.new(@data_table, opts)
|
|
27
|
-
end
|
|
26
|
+
##### Adding column header #####
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@gruff.title = title
|
|
32
|
-
@gruff.theme = Gruff::Themes::GOOGLE_CHART
|
|
33
|
-
@rows.each do |row|
|
|
34
|
-
@gruff.data(row[0], row[1])
|
|
28
|
+
@columns.each_with_index do |column, i|
|
|
29
|
+
@data_table.add_row([column.title, @data[i]])
|
|
35
30
|
end
|
|
31
|
+
|
|
32
|
+
options = {:title => title, backgroundColor: 'transparent'}.merge(@options)
|
|
33
|
+
GoogleVisualr::Interactive::PieChart.new(@data_table, options)
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def to_blob
|
|
39
|
-
|
|
40
|
-
@gruff.to_blob
|
|
37
|
+
super(:pie)
|
|
41
38
|
end
|
|
42
39
|
end
|
|
43
40
|
end
|
|
@@ -1,116 +1,20 @@
|
|
|
1
|
-
module
|
|
2
|
-
module
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# A color scheme plucked from the colors on the popular usability blog.
|
|
20
|
-
THIRTYSEVEN_SIGNALS = {
|
|
21
|
-
:colors => [
|
|
22
|
-
'#FFF804', # yellow
|
|
23
|
-
'#336699', # blue
|
|
24
|
-
'#339933', # green
|
|
25
|
-
'#ff0000', # red
|
|
26
|
-
'#cc99cc', # purple
|
|
27
|
-
'#cf5910', # orange
|
|
28
|
-
'black'
|
|
29
|
-
],
|
|
30
|
-
:marker_color => 'black',
|
|
31
|
-
:font_color => 'black',
|
|
32
|
-
:background_colors => ['#d1edf5', 'white']
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
# A color scheme from the colors used on the 2005 Rails keynote
|
|
36
|
-
# presentation at RubyConf.
|
|
37
|
-
RAILS_KEYNOTE = {
|
|
38
|
-
:colors => [
|
|
39
|
-
'#00ff00', # green
|
|
40
|
-
'#333333', # grey
|
|
41
|
-
'#ff5d00', # orange
|
|
42
|
-
'#f61100', # red
|
|
43
|
-
'white',
|
|
44
|
-
'#999999', # light grey
|
|
45
|
-
'black'
|
|
46
|
-
],
|
|
47
|
-
:marker_color => 'white',
|
|
48
|
-
:font_color => 'white',
|
|
49
|
-
:background_colors => ['#0083a3', '#0083a3']
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# A color scheme similar to that used on the popular podcast site.
|
|
53
|
-
ODEO = {
|
|
54
|
-
:colors => [
|
|
55
|
-
'#202020', # grey
|
|
56
|
-
'white',
|
|
57
|
-
'#3a5b87', # dark blue
|
|
58
|
-
'#a21764', # dark pink
|
|
59
|
-
'#8ab438', # green
|
|
60
|
-
'#999999', # light grey
|
|
61
|
-
'black'
|
|
62
|
-
],
|
|
63
|
-
:marker_color => 'white',
|
|
64
|
-
:font_color => 'white',
|
|
65
|
-
:background_colors => ['#ff47a4', '#ff1f81']
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
# A pastel theme
|
|
69
|
-
PASTEL = {
|
|
70
|
-
:colors => [
|
|
71
|
-
'#a9dada', # blue
|
|
72
|
-
'#aedaa9', # green
|
|
73
|
-
'#daaea9', # peach
|
|
74
|
-
'#dadaa9', # yellow
|
|
75
|
-
'#a9a9da', # dk purple
|
|
76
|
-
'#daaeda', # purple
|
|
77
|
-
'#dadada' # grey
|
|
78
|
-
],
|
|
79
|
-
:marker_color => '#aea9a9', # Grey
|
|
80
|
-
:font_color => 'black',
|
|
81
|
-
:background_colors => 'white'
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
# A greyscale theme
|
|
85
|
-
GREYSCALE = {
|
|
86
|
-
:colors => [
|
|
87
|
-
'#282828', #
|
|
88
|
-
'#383838', #
|
|
89
|
-
'#686868', #
|
|
90
|
-
'#989898', #
|
|
91
|
-
'#c8c8c8', #
|
|
92
|
-
'#e8e8e8', #
|
|
93
|
-
],
|
|
94
|
-
:marker_color => '#aea9a9', # Grey
|
|
95
|
-
:font_color => 'black',
|
|
96
|
-
:background_colors => 'white'
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
# A pastel theme
|
|
100
|
-
GOOGLE_CHART = {
|
|
101
|
-
:colors => [
|
|
102
|
-
'#3366CC', # blue
|
|
103
|
-
'#DC3912', # red
|
|
104
|
-
'#FF9900', # yellow
|
|
105
|
-
'#109618', # green
|
|
106
|
-
'#990099', # dk purple
|
|
107
|
-
'#0099C6', # sky
|
|
108
|
-
'#DD4477' # grey
|
|
109
|
-
],
|
|
110
|
-
:marker_color => '#aea9a9', # Grey
|
|
111
|
-
:font_color => 'black',
|
|
112
|
-
:background_colors => 'white'
|
|
113
|
-
}
|
|
114
|
-
|
|
1
|
+
module QueryReport
|
|
2
|
+
module Chart
|
|
3
|
+
module Themes
|
|
4
|
+
GOOGLE_CHART = {
|
|
5
|
+
:colors => [
|
|
6
|
+
'#3366CC', # blue
|
|
7
|
+
'#DC3912', # red
|
|
8
|
+
'#FF9900', # yellow
|
|
9
|
+
'#109618', # green
|
|
10
|
+
'#990099', # dk purple
|
|
11
|
+
'#0099C6', # sky
|
|
12
|
+
'#DD4477' # grey
|
|
13
|
+
],
|
|
14
|
+
:marker_color => '#aea9a9', # Grey
|
|
15
|
+
:font_color => 'black',
|
|
16
|
+
:background_colors => 'white'
|
|
17
|
+
}
|
|
18
|
+
end
|
|
115
19
|
end
|
|
116
20
|
end
|
data/lib/query_report/column.rb
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
|
+
# Author:: A.K.M. Ashrafuzzaman (mailto:ashrafuzzaman.g2@gmail.com)
|
|
2
|
+
# License:: MIT-LICENSE
|
|
3
|
+
|
|
4
|
+
# The purpose of the column module is to define columns that are displayed in the views
|
|
5
|
+
|
|
1
6
|
module QueryReport
|
|
2
7
|
module ColumnModule
|
|
3
|
-
|
|
4
|
-
options.merge!(model_name: model_name)
|
|
5
|
-
@columns << Column.new(name, options, block)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def columns
|
|
9
|
-
@columns
|
|
10
|
-
end
|
|
8
|
+
attr_accessor :columns
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
# Creates a filter and adds to the filters
|
|
11
|
+
# Params:
|
|
12
|
+
# +column+:: the column on which the filter is done on
|
|
13
|
+
# +options+:: Options can have the following,
|
|
14
|
+
# options[:type] => date | text | whatever
|
|
15
|
+
# options[:comp] => the comparators used for ransack search, [:gteq, :lteq]
|
|
16
|
+
# options[:only_on_web] => the column will appear on the web and not appear in PDF or csv if set to true
|
|
17
|
+
def column(name, options={}, &block)
|
|
18
|
+
@columns << Column.new(self, name, options, block)
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
class Column
|
|
17
|
-
attr_reader :name, :options, :type, :data
|
|
22
|
+
attr_reader :report, :name, :options, :type, :data
|
|
23
|
+
|
|
24
|
+
def initialize(report, column_name, options={}, block = nil)
|
|
25
|
+
@report, @name, @options = report, column_name, options
|
|
26
|
+
@type = @report.model_class.columns_hash[column_name.to_s].try(:type) || options[:type] || :string
|
|
27
|
+
@data = block || column_name.to_sym
|
|
28
|
+
end
|
|
18
29
|
|
|
19
|
-
def
|
|
20
|
-
@
|
|
21
|
-
@options = options
|
|
22
|
-
@type = (options.kind_of?(Hash) ? options[:type] : options) || 'string'
|
|
23
|
-
@data = block || name.to_sym
|
|
30
|
+
def only_on_web?
|
|
31
|
+
@options[:only_on_web] == true
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
def humanize
|
|
27
|
-
options[:as] ||
|
|
35
|
+
@humanize ||= options[:as] || @report.model_class.human_attribute_name(name)
|
|
28
36
|
end
|
|
29
|
-
end
|
|
30
37
|
|
|
38
|
+
def value(record)
|
|
39
|
+
self.data.kind_of?(Symbol) ? record.send(self.name) : self.data.call(record)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
31
42
|
end
|
|
32
43
|
end
|
data/lib/query_report/filter.rb
CHANGED
|
@@ -1,38 +1,102 @@
|
|
|
1
|
+
# Author:: A.K.M. Ashrafuzzaman (mailto:ashrafuzzaman.g2@gmail.com)
|
|
2
|
+
# License:: MIT-LICENSE
|
|
3
|
+
|
|
4
|
+
# The purpose of the filter module is to add feature
|
|
5
|
+
# to support report tool to add custom and predefined filters
|
|
6
|
+
|
|
1
7
|
module QueryReport
|
|
2
8
|
module FilterModule
|
|
3
|
-
|
|
9
|
+
attr_accessor :filters, :search
|
|
10
|
+
|
|
11
|
+
# Creates a filter and adds to the filters
|
|
12
|
+
# Params:
|
|
13
|
+
# +column+:: the column on which the filter is done on
|
|
14
|
+
# +options+:: Options can have the following,
|
|
15
|
+
# options[:type] => date | text | whatever
|
|
16
|
+
# options[:comp] => the comparators used for ransack search, [:gteq, :lteq]
|
|
17
|
+
def filter(column, options={}, &block)
|
|
18
|
+
@filters ||= []
|
|
4
19
|
@filters << Filter.new(@params, column, options, &block)
|
|
5
20
|
end
|
|
6
21
|
|
|
7
|
-
def
|
|
8
|
-
|
|
22
|
+
def apply_filters(query, http_params)
|
|
23
|
+
# apply default filter
|
|
24
|
+
params = load_default_values_in_param(http_params) #need for ransack filter
|
|
25
|
+
|
|
26
|
+
@search = query.search(params[:q])
|
|
27
|
+
query = @search.result
|
|
28
|
+
|
|
9
29
|
@filters.each do |filter|
|
|
10
|
-
|
|
30
|
+
if filter.custom?
|
|
31
|
+
ordered_custom_param_values = filter.search_keys.collect do |key|
|
|
32
|
+
if filter.boolean?
|
|
33
|
+
params[:custom_search][key].present? ? params[:custom_search][key] == 'true' : nil
|
|
34
|
+
else
|
|
35
|
+
params[:custom_search][key]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
#filter only if there is a given input
|
|
39
|
+
query = filter.block.call(query, *ordered_custom_param_values) unless ordered_custom_param_values.all? { |p| p.nil? or p == '' }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
query
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def load_default_values_in_param(http_params)
|
|
46
|
+
params = http_params.clone
|
|
47
|
+
params = params.merge(q: {}) unless params[:q]
|
|
48
|
+
params = params.merge(custom_search: {}) unless params[:custom_search]
|
|
49
|
+
@filters.each do |filter|
|
|
50
|
+
if filter.has_default?
|
|
51
|
+
filter.comparators.each do |comparator|
|
|
52
|
+
params[filter.params_key][comparator.search_key] ||= comparator.default.to_s
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
params
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class Comparator
|
|
60
|
+
attr_reader :filter, :type, :name, :default
|
|
61
|
+
|
|
62
|
+
def initialize(filter, type, name, default=nil)
|
|
63
|
+
@filter, @type, @name, @default = filter, type, name, default.to_s
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def search_key
|
|
67
|
+
"#{@filter.column.to_s}_#{@type}".to_sym
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def search_tag_name
|
|
71
|
+
"#{@filter.params_key}[#{search_key.to_s}]"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def param_value
|
|
75
|
+
@filter.params[@filter.params_key] ? @filter.params[@filter.params_key][search_key] : default
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def has_default?
|
|
79
|
+
!@default.nil?
|
|
11
80
|
end
|
|
12
|
-
hash
|
|
13
81
|
end
|
|
14
82
|
|
|
15
83
|
class Filter
|
|
16
|
-
attr_reader :params, :column, :type, :comparators, :block, :
|
|
84
|
+
attr_reader :params, :column, :type, :comparators, :block, :options
|
|
17
85
|
|
|
86
|
+
# Initializes filter with the proper parameters
|
|
87
|
+
# Params:
|
|
88
|
+
# +params+:: The params from the http request
|
|
18
89
|
def initialize(params, column, options, &block)
|
|
19
|
-
@params = params
|
|
20
|
-
@column = column
|
|
90
|
+
@params, @column, @options, @comparators, @block = params, column, options, [], block
|
|
21
91
|
@type = options if options.kind_of? String
|
|
22
92
|
if options.kind_of? Hash
|
|
23
93
|
@type = options[:type]
|
|
24
|
-
@comparators = options[:comp] || detect_comparators(@type)
|
|
25
94
|
end
|
|
26
|
-
|
|
27
|
-
@custom = @block ? true : false
|
|
95
|
+
generate_comparators
|
|
28
96
|
end
|
|
29
97
|
|
|
30
98
|
def self.supported_types
|
|
31
|
-
[:date, :text]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def keys
|
|
35
|
-
@keys ||= (@comparators || {}).keys.map { |comp| "#{column.to_s}_#{comp}" }
|
|
99
|
+
[:date, :text, :boolean]
|
|
36
100
|
end
|
|
37
101
|
|
|
38
102
|
supported_types.each do |supported_type|
|
|
@@ -41,25 +105,40 @@ module QueryReport
|
|
|
41
105
|
end
|
|
42
106
|
end
|
|
43
107
|
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
108
|
+
def custom?
|
|
109
|
+
@block ? true : false
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def search_keys
|
|
113
|
+
@comparators.collect(&:search_key)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def has_default?
|
|
117
|
+
@comparators.any?(&:has_default?)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def params_key
|
|
121
|
+
custom? ? :custom_search : :q
|
|
52
122
|
end
|
|
53
123
|
|
|
54
124
|
private
|
|
55
|
-
def
|
|
56
|
-
case type
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
125
|
+
def generate_comparators
|
|
126
|
+
@options[:comp] ||= case @type
|
|
127
|
+
when :date
|
|
128
|
+
{gteq: I18n.t('query_report.filters.from'), lteq: I18n.t('query_report.filters.to')}
|
|
129
|
+
when :text
|
|
130
|
+
{cont: I18n.t("query_report.filters.#{@column.to_s}.contains")}
|
|
131
|
+
else
|
|
132
|
+
{eq: I18n.t("query_report.filters.#{@column.to_s}.equals")}
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
if @options[:comp]
|
|
136
|
+
@options[:comp].each_with_index do |(search_key, filter_name), i|
|
|
137
|
+
default = nil
|
|
138
|
+
default = @options[:default].kind_of?(Array) ? @options[:default][i] : @options[:default] if @options[:default]
|
|
139
|
+
@comparators << Comparator.new(self, search_key, filter_name, default)
|
|
140
|
+
end
|
|
61
141
|
end
|
|
62
|
-
{eq: I18n.t('query_report.filters.equal')}
|
|
63
142
|
end
|
|
64
143
|
end
|
|
65
144
|
end
|