reporta-modules 0.0.1

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 (81) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +203 -0
  4. data/Rakefile +20 -0
  5. data/lib/generators/reporta/views_generator.rb +24 -0
  6. data/lib/generators/templates/reports/_box.html.erb +48 -0
  7. data/lib/generators/templates/reports/_chartjs_bar.html.erb +31 -0
  8. data/lib/generators/templates/reports/_chartjs_line.html.erb +33 -0
  9. data/lib/generators/templates/reports/_chartjs_pie.html.erb +19 -0
  10. data/lib/generators/templates/reports/_filters.html.erb +100 -0
  11. data/lib/generators/templates/reports/_table.html.erb +49 -0
  12. data/lib/reporta-modules.rb +15 -0
  13. data/lib/reporta/box_helper.rb +17 -0
  14. data/lib/reporta/chartjs_helper.rb +74 -0
  15. data/lib/reporta/models/column.rb +68 -0
  16. data/lib/reporta/models/filter.rb +42 -0
  17. data/lib/reporta/models/form.rb +77 -0
  18. data/lib/reporta/models/reportable.rb +50 -0
  19. data/lib/reporta/railtie.rb +8 -0
  20. data/lib/reporta/version.rb +3 -0
  21. data/lib/reporta/view_helper.rb +38 -0
  22. data/lib/tasks/reporta_tasks.rake +4 -0
  23. data/spec/dummy/README.rdoc +28 -0
  24. data/spec/dummy/Rakefile +6 -0
  25. data/spec/dummy/app/assets/javascripts/application.js +18 -0
  26. data/spec/dummy/app/assets/javascripts/jquery.dataTables.js +12099 -0
  27. data/spec/dummy/app/assets/javascripts/jquery.flot.js +3061 -0
  28. data/spec/dummy/app/assets/javascripts/jquery.flot.time.js +431 -0
  29. data/spec/dummy/app/assets/javascripts/jquery.js +2 -0
  30. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  31. data/spec/dummy/app/assets/stylesheets/bootstrap.min.css +9 -0
  32. data/spec/dummy/app/assets/stylesheets/style.css +57 -0
  33. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  34. data/spec/dummy/app/controllers/reports_controller.rb +18 -0
  35. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  36. data/spec/dummy/app/models/account.rb +3 -0
  37. data/spec/dummy/app/models/account_chart.rb +41 -0
  38. data/spec/dummy/app/models/account_report.rb +39 -0
  39. data/spec/dummy/app/models/user.rb +8 -0
  40. data/spec/dummy/app/views/layouts/application.html.erb +28 -0
  41. data/spec/dummy/app/views/reports/chart.html.erb +6 -0
  42. data/spec/dummy/app/views/reports/dynamic_table.html.erb +33 -0
  43. data/spec/dummy/app/views/reports/dynamic_table_with_bootstrap.html.erb +37 -0
  44. data/spec/dummy/app/views/reports/overview.html.erb +4 -0
  45. data/spec/dummy/app/views/reports/table.html.erb +12 -0
  46. data/spec/dummy/bin/bundle +3 -0
  47. data/spec/dummy/bin/rails +4 -0
  48. data/spec/dummy/bin/rake +4 -0
  49. data/spec/dummy/config.ru +4 -0
  50. data/spec/dummy/config/application.rb +23 -0
  51. data/spec/dummy/config/boot.rb +5 -0
  52. data/spec/dummy/config/database.yml +25 -0
  53. data/spec/dummy/config/environment.rb +5 -0
  54. data/spec/dummy/config/environments/development.rb +29 -0
  55. data/spec/dummy/config/environments/production.rb +80 -0
  56. data/spec/dummy/config/environments/test.rb +36 -0
  57. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  59. data/spec/dummy/config/initializers/inflections.rb +16 -0
  60. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  61. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  62. data/spec/dummy/config/initializers/session_store.rb +3 -0
  63. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  64. data/spec/dummy/config/locales/en.yml +23 -0
  65. data/spec/dummy/config/routes.rb +7 -0
  66. data/spec/dummy/db/migrate/20130622041213_create_users.rb +14 -0
  67. data/spec/dummy/db/migrate/20130623054801_create_accounts.rb +9 -0
  68. data/spec/dummy/db/schema.rb +33 -0
  69. data/spec/dummy/db/seeds.rb +20 -0
  70. data/spec/dummy/db/test.sqlite3 +0 -0
  71. data/spec/dummy/log/test.log +1190 -0
  72. data/spec/dummy/public/404.html +58 -0
  73. data/spec/dummy/public/422.html +58 -0
  74. data/spec/dummy/public/500.html +57 -0
  75. data/spec/dummy/public/favicon.ico +0 -0
  76. data/spec/models/column_spec.rb +76 -0
  77. data/spec/models/filter_spec.rb +63 -0
  78. data/spec/models/form_spec.rb +81 -0
  79. data/spec/models/report_spec.rb +51 -0
  80. data/spec/spec_helper.rb +43 -0
  81. metadata +247 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24231287130d42d72c0e84992b2bea414f81289b
4
+ data.tar.gz: 6d19674561f3ae544758cb1f11ddbb096429f471
5
+ SHA512:
6
+ metadata.gz: 25052bfc227fda62f69bb12aba5b783b9a74681153c4c2922b8c013c866a67f11a598d356f39e2411887356797a700465cbd1cbd821538ea6f7fe159c1ca0bec
7
+ data.tar.gz: 74616e062c0781180563f51f2fa82c4bd75a6df85e15afb5e16e3c9108bb8f1e48224444173191e397700acc53c68f4d0823309c6187b2ea8abf3b3dc7e6a1ff
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Alvin S.J. Ng
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,203 @@
1
+ # Reporta Modules
2
+
3
+ __reporta-modules__ is a Rails gem packed with modules and helpers to help you build your reports.
4
+
5
+ It is also a fork from the original [__reporta__](github.com/uts/reporta) Rails engine gem.
6
+
7
+ ## Installation
8
+
9
+ Add Reporta to your Gemfile
10
+
11
+ ```ruby
12
+ gem 'reporta-modules'
13
+ ```
14
+
15
+ Generate default view templates in your project
16
+ `$ rails generate reporta:views`
17
+
18
+ Turn any plain Ruby class into a Reporta class by including `Reporta::Reportable`
19
+
20
+ ```ruby
21
+ class YourReport
22
+ include Reporta::Reportable
23
+ end
24
+ ```
25
+
26
+ ## Basic Example
27
+
28
+ ### View Model
29
+
30
+ ```ruby
31
+ class ProjectReport
32
+ include Reporta::Reportable
33
+
34
+ filter :start_date, default: '2013-01-01', required: true
35
+ filter :finish_date, default: '2013-12-13', required: true
36
+
37
+ column :name
38
+ column :created_at
39
+
40
+ def rows
41
+ Project.where(created_at: start_date..finish_date)
42
+ end
43
+ end
44
+ ```
45
+
46
+ ### Controller
47
+
48
+ ```ruby
49
+ class ProjectReportsController < ApplicationController
50
+ def show
51
+ @report = ProjectsReport.new(params[:reporta_form])
52
+ end
53
+ end
54
+ ```
55
+
56
+ ### View
57
+
58
+ ```erb
59
+ <%= filters_for @report %>
60
+ <%= table_for @report %>
61
+ ```
62
+
63
+
64
+
65
+ ## Reporta Modules
66
+
67
+ ### Reporta::Reportable
68
+
69
+ `Reporta::Reportable` module added some DSL for your covenience to create your report's [__view model/object__](http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/).
70
+
71
+ #### Filters
72
+
73
+ Report are normally generated based on some filter or a certain criteria.
74
+ For example:
75
+
76
+ ```ruby
77
+ class ProjectReport
78
+ include Reporta::Reportable
79
+
80
+ filter :start_date, as: :date, default: '2013-01-01', required: true
81
+ filter :finish_date, as: :date, default: '2013-12-31', required: true
82
+ filter :status, collection: Status.all, include_blank: false
83
+ filter :exclude_deleted, as: :boolean, default: false
84
+
85
+ # required method
86
+ def rows
87
+ # use filters above to manipulate the results
88
+ projects = Project.where(created_at: start_date..finish_date)
89
+ .where(status: status)
90
+ projects = projects.where(deleted_at: nil) if exclude_deleted
91
+ projects
92
+ end
93
+ end
94
+ ```
95
+
96
+ **Filter Options**
97
+
98
+ * `required` - set to `true` to force a field to be set. Defaults to `false`.
99
+ * `collection` - setting a collection will force the filter to render as a select input.
100
+ * `include_blank` - only has an affect if a collection is set. defaults to `true`.
101
+ * `as` - set the type of field to render. Available values are `:boolean`, `:string`, `:check_boxes`, `:radio`, `:date`. Defaults to `:string`.
102
+ * `default` - set the default value for the filter.
103
+ * `label` - set the label of display
104
+
105
+ #### Columns
106
+
107
+ When is comes to displaying the report you will generally want to display a subset of data from the rows, custom calculations or maybe some associated data. Here's a quick example of defining a variety of columns.
108
+
109
+ ```ruby
110
+ class ProjectReport
111
+ include Reporta::Reportable
112
+
113
+ column :name
114
+ column :formatted_date, title: 'Created at'
115
+ column :manager, data_chain: 'manager.full_name'
116
+ column :cost, class_names: 'sum currency'
117
+
118
+ def rows
119
+ Projects.all
120
+ end
121
+
122
+ def formatted_date(project)
123
+ project.created_at.strftime("%b %d, %Y")
124
+ end
125
+ end
126
+ ```
127
+
128
+ **Column Options**
129
+
130
+ * `title` - set a custom title for the colum. Defaults to the column name
131
+ * `data_chain` - provide a chain of methods to call in order to fetch the data.
132
+ * `class_names` - these classes will be applied to the column to allow for custom styling or Javascript hooks.
133
+ * `helper` - format your column
134
+
135
+ ### Required Methods
136
+
137
+ As a very minimum you need to define the `rows` method which will return the rows that are displayed in the report.
138
+
139
+ ```ruby
140
+ class ProjectReport
141
+ include Reporta::Reportable
142
+
143
+ def rows
144
+ Project.all
145
+ end
146
+ end
147
+ ```
148
+
149
+
150
+ #### Default View Templates
151
+
152
+ In order to render the results of your report there are a variety of different ways to access and display the data. If you have any filters defined you will probably want to display a form for the user to enter parameters into.
153
+
154
+ The `filters_for` helper generates a basic form based on the filters you have defined.
155
+
156
+ ```erb
157
+ <%= filters_for @report %>
158
+ ```
159
+ If we look at how `filters_for` is created you can see the underlying data structures used to render the form.
160
+
161
+ ```erb
162
+ <%= form_for @report.form do |f| %>
163
+ <% @report.filters.each do |filter| %>
164
+ <%= f.label filter.name %>
165
+ <%= f.text_field filter.name %>
166
+ <% end %>
167
+ <%= f.submit %>
168
+ <% end %>
169
+ ```
170
+ To display the results of the report you can simply use the `table_for` helper method.
171
+
172
+ ```erb
173
+ <%= table_for @report %>
174
+ ```
175
+ Or for more detailed control you can build the table yourself.
176
+
177
+ ```erb
178
+ <table>
179
+ <thead>
180
+ <tr>
181
+ <% @report.columns.each do |column| %>
182
+ <th class="#{column.class_names}">
183
+ <%= column.title %>
184
+ </th>
185
+ <% end %>
186
+ </tr>
187
+ </thead>
188
+ <tbody>
189
+ <% @report.rows.each do |record| %>
190
+ <tr>
191
+ <% @report.columns.each do |column| %>
192
+ <th class="#{column.class_names}">
193
+ <%= @report.value_for(record, column) %>
194
+ </th>
195
+ <% end %>
196
+ </tr>
197
+ <% end %>
198
+ </tbody>
199
+ </table>
200
+ ```
201
+
202
+ ## License
203
+ see MIT-LICENSE
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
8
+ load 'rails/tasks/engine.rake'
9
+
10
+ Bundler::GemHelper.install_tasks
11
+
12
+ require 'rake/testtask'
13
+
14
+ Rake::TestTask.new(:test) do |t|
15
+ t.libs = ["lib", "spec"]
16
+ t.test_files = FileList['spec/**/*_spec.rb']
17
+ end
18
+
19
+
20
+ task default: :test
@@ -0,0 +1,24 @@
1
+ require 'rails/generators/base'
2
+
3
+ module Reporta
4
+ module Generators
5
+ class ViewsGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../../templates", __FILE__)
7
+ public_task :copy_views
8
+
9
+ def copy_views
10
+ view_directory :reports
11
+ end
12
+
13
+ def view_directory(name, _target_path = nil)
14
+ directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
15
+ content
16
+ end
17
+ end
18
+
19
+ def target_path
20
+ @target_path ||= "app/views/reporta"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ <div class="well">
2
+ <div class="reporta-box">
3
+ <span class="box-icon <%=report.icon_bg %>" >
4
+ <!-- uses FontAwesome -->
5
+ <i class="fa <%=report.fa_icon %>"></i>
6
+ </span>
7
+ <span class="box-info">
8
+ <p class="value"><%= raw report.value %></p>
9
+ <p class="title"><%= raw report.description %></p>
10
+ </span>
11
+ </div>
12
+ </div>
13
+ <!--
14
+ <style>
15
+ .reporta-box .box-icon{
16
+ display: block;
17
+ float: left;
18
+ margin: 0 10px 10px 0;
19
+ width: 65px;
20
+ height: 65px;
21
+ border-radius: 50%;
22
+ vertical-align: middle;
23
+ text-align: center;
24
+ font-size: 35px;
25
+ line-height: 65px;
26
+ }
27
+ .reporta-box i.fa{
28
+ line-height: 35px;
29
+ text-align:center;
30
+ color: white;
31
+ }
32
+
33
+ .reporta-box .box-info p{
34
+ margin:0;
35
+ }
36
+
37
+ .reporta-box .box-info .value{
38
+ color: #767676;
39
+ font-size: 30px;
40
+ }
41
+
42
+ .reporta-box .box-info .title{
43
+ color: #999999;
44
+ font-size: 14px;
45
+ }
46
+ </style>
47
+ -->
48
+
@@ -0,0 +1,31 @@
1
+ <canvas id="<%=prefix.to_s.camelize %>BarChart"></canvas>
2
+ <% content_for :script do %>
3
+ // uses JQuery
4
+ $(function(){
5
+ "use strict";
6
+ var data = {
7
+ labels : <%=raw labels_from_rows(rows, x).to_json %>,
8
+ datasets : [
9
+ <% y = [y] if !y.is_a?(Array) %>
10
+ <% lines = y.map do |k|
11
+ "{
12
+ fillColor : '#{color}',
13
+ strokeColor : '#{color}',
14
+ pointColor : '#{color}',
15
+ pointStrokeColor : '#fff',
16
+ data : #{raw decimals_from_rows(rows, x, k).to_json}
17
+ }"
18
+ end.join(',') %>
19
+ <%=raw lines %>
20
+ ]
21
+ };
22
+
23
+ var ctx = document.getElementById("<%=prefix.to_s.camelize %>BarChart").getContext("2d");
24
+
25
+ // uses Chartjs
26
+ var chart = new Chart(ctx).Bar(data, {responsive: true});
27
+ <%= yield :chartjs_script %>
28
+ });
29
+
30
+ <% end %>
31
+
@@ -0,0 +1,33 @@
1
+ <canvas id="<%=prefix.to_s.camelize %>LineChart"></canvas>
2
+ <% content_for :script do %>
3
+
4
+ // uses JQuery
5
+ $(function(){
6
+ "use strict";
7
+
8
+ var data = {
9
+ labels : <%=raw labels_from_rows(rows, x).to_json %>,
10
+ datasets : [
11
+ <% y = [y] if !y.is_a?(Array) %>
12
+ <% lines = y.map do |k|
13
+ "{
14
+ fillColor : '#{color}',
15
+ strokeColor : '#{color}',
16
+ pointColor : '#{color}',
17
+ pointStrokeColor : '#fff',
18
+ data : #{raw decimals_from_rows(rows, x, k).to_json}
19
+ }"
20
+ end.join(',') %>
21
+ <%=raw lines %>
22
+ ]
23
+ };
24
+
25
+ var ctx = document.getElementById("<%=prefix.to_s.camelize %>LineChart").getContext("2d");
26
+
27
+ // uses Chartjs
28
+ var chart = new Chart(ctx).Line(data, {responsive: true});
29
+ <%= yield :chartjs_script %>
30
+ });
31
+
32
+ <% end %>
33
+
@@ -0,0 +1,19 @@
1
+ <div class="col-md-6">
2
+ <canvas id="<%=prefix.to_s.camelize %>PieChart" ></canvas>
3
+ </div>
4
+ <div class="col-md-6">
5
+ <div id="<%=prefix.to_s.camelize%>PieChartLegend"></div>
6
+ </div>
7
+ <% chart = chart_pie_from_rows(rows, x, y) %>
8
+ <% content_for :script do %>
9
+ $(function(){
10
+ "use strict";
11
+
12
+ var data = <%=raw chart[:datasets] %>;
13
+ var ctx = document.getElementById("<%=prefix.to_s.camelize %>PieChart").getContext("2d");
14
+ var chart = new Chart(ctx).Pie(data, {responsive: true});
15
+ $('#<%=prefix.to_s.camelize %>PieChartLegend').html(chart.generateLegend());
16
+ <%= yield :chartjs_script %>
17
+ });
18
+ <% end %>
19
+
@@ -0,0 +1,100 @@
1
+ <!--
2
+ Copyright 2013-2014 University of Technology, Sydney (github.com/uts)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ -->
23
+
24
+ <%= form_for report.form, url: request.path, html:{class: 'form-horizontal well'} do |f| %>
25
+ <%
26
+ non_advanced = report.filters.select{|k,o| !o.advanced}
27
+ advanced = report.filters.select{|k,o| o.advanced }
28
+ %>
29
+ <% [non_advanced, advanced].each do |filters| %>
30
+ <div id="<%=raw('form-advanced" style="display:none') if filters == advanced%>">
31
+ <% filters.each do |name, options| %>
32
+
33
+ <% label_name = options.label || ("#{name.to_s.humanize} #{'*' if options.required}") %>
34
+ <div class='form-group'>
35
+ <%#Collection field%>
36
+ <% if options.collection %>
37
+ <%= f.label name, label_name, class: 'col-sm-2 control-label' %>
38
+ <div class='col-sm-10'>
39
+ <% html_opts = options.include_blank ? {include_blank: options.include_blank} : {} %>
40
+ <%= f.select name, options_for_select(options.collection, f.object.send(name)), html_opts, required: options.required, multiple: options.multiple%>
41
+ </div>
42
+
43
+ <%#Boolean field%>
44
+ <% elsif options.boolean? %>
45
+ <div class="col-sm-offset-2 col-sm-10">
46
+ <label>
47
+ <%= f.check_box name %> <%=label_name %>
48
+ </label>
49
+ </div>
50
+
51
+ <%#Date field%>
52
+ <% elsif options.as == :date %>
53
+ <%= f.label name, label_name, class: 'col-sm-2 control-label text-left' %>
54
+ <div class="col-sm-10">
55
+ <%= f.text_field name, required: options.required, class: "#{name}-datepicker" %>
56
+ </div>
57
+ <!--
58
+ // uses JQuery
59
+ $(function(){
60
+ // uses JQueryUI
61
+ $('input.<%=name.to_s%>-datepicker').datepicker({
62
+ changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd'
63
+ });
64
+ });
65
+ -->
66
+
67
+ <%#Text field%>
68
+ <% else %>
69
+ <%= f.label name, label_name, class: 'col-sm-2 control-label text-left' %>
70
+ <div class="col-sm-10">
71
+ <%= f.text_field name, required: options.required %>
72
+ </div>
73
+ <% end %>
74
+ </div>
75
+
76
+ <% if report.form.errors[name].any? %>
77
+ <%= report.form.errors[name].to_sentence %>
78
+ <% end %>
79
+ <% end %>
80
+ </div>
81
+
82
+ <% if advanced.present? && non_advanced == filters %>
83
+ <div class="form-group">
84
+ <div class="col-sm-offset-2 col-sm-10">
85
+ <a href="#" id='toggle-advanced'>Show Advanced Options</a>
86
+ </div>
87
+ </div>
88
+ <% end %>
89
+
90
+ <% end %>
91
+
92
+ <div class="form-group">
93
+ <div class="col-sm-offset-2 col-sm-10">
94
+ <%= f.button 'Apply', class: 'btn btn-primary' %>
95
+ <%= link_to 'Reset all', request.original_url, class: 'btn btn-default' %>
96
+ </div>
97
+ </div>
98
+
99
+ <% end %>
100
+