rails_info 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +58 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/rails_info/application.js +6 -0
  5. data/app/assets/javascripts/rails_info/base.js.coffee +6 -0
  6. data/app/assets/javascripts/rails_info/bootstrap.js.coffee +4 -0
  7. data/app/assets/stylesheets/rails_info/application.css +14 -0
  8. data/app/assets/stylesheets/rails_info/base.css.scss +22 -0
  9. data/app/assets/stylesheets/rails_info/bootstrap_and_overrides.css.less +63 -0
  10. data/app/assets/stylesheets/rails_info/exception.css +17 -0
  11. data/app/assets/stylesheets/rails_info/exception/base.css.scss +31 -0
  12. data/app/assets/stylesheets/rails_info/exception/pygments.css.erb +5 -0
  13. data/app/controllers/rails_info/data_controller.rb +9 -0
  14. data/app/controllers/rails_info/logs/server_controller.rb +10 -0
  15. data/app/controllers/rails_info/logs/test/rspec_controller.rb +16 -0
  16. data/app/controllers/rails_info/model_controller.rb +5 -0
  17. data/app/controllers/rails_info/properties_controller.rb +4 -0
  18. data/app/controllers/rails_info/routes_controller.rb +4 -0
  19. data/app/controllers/rails_info/stack_traces_controller.rb +11 -0
  20. data/app/controllers/rails_info_controller.rb +16 -0
  21. data/app/helpers/rails_info/resources_helper.rb +194 -0
  22. data/app/presenters/rails_info/code_presenter.rb +63 -0
  23. data/app/presenters/rails_info/data/object_presenter.rb +34 -0
  24. data/app/presenters/rails_info/data/row_set_presenter.rb +38 -0
  25. data/app/presenters/rails_info/data_presenter.rb +21 -0
  26. data/app/presenters/rails_info/logs/server/action_presenter.rb +109 -0
  27. data/app/presenters/rails_info/logs/server_presenter.rb +57 -0
  28. data/app/presenters/rails_info/logs/test/rspec/file_presenter.rb +87 -0
  29. data/app/presenters/rails_info/logs/test/rspec_presenter.rb +32 -0
  30. data/app/presenters/rails_info/model_presenter.rb +68 -0
  31. data/app/presenters/rails_info/presenter.rb +19 -0
  32. data/app/presenters/rails_info/stack_trace_presenter.rb +98 -0
  33. data/app/views/layouts/_layout.html.erb +19 -0
  34. data/app/views/layouts/rails_info.html.erb +1 -0
  35. data/app/views/layouts/rails_info/exception.html.erb +1 -0
  36. data/app/views/layouts/shared/_navigation.html.erb +7 -0
  37. data/app/views/rails_info/data/index.html.erb +23 -0
  38. data/app/views/rails_info/logs/server/_table.html.erb +16 -0
  39. data/app/views/rails_info/logs/server/new.html.erb +19 -0
  40. data/app/views/rails_info/logs/test/rspec/new.html.erb +10 -0
  41. data/app/views/rails_info/model/index.html.erb +14 -0
  42. data/app/views/rails_info/properties/index.html.erb +1 -0
  43. data/app/views/rails_info/routes/index.html.erb +18 -0
  44. data/app/views/rails_info/stack_traces/_accordion.html.erb +1 -0
  45. data/app/views/rails_info/stack_traces/_form.html.erb +11 -0
  46. data/app/views/rails_info/stack_traces/_with_request_and_response.html.erb +16 -0
  47. data/app/views/rails_info/stack_traces/new.html.erb +10 -0
  48. data/config/navigation.rb +20 -0
  49. data/config/routes.rb +20 -0
  50. data/lib/rails_info.rb +19 -0
  51. data/lib/rails_info/controller.rb +2 -0
  52. data/lib/rails_info/controller/exception_diagnostics.rb +28 -0
  53. data/lib/rails_info/data.rb +55 -0
  54. data/lib/rails_info/engine.rb +9 -0
  55. data/lib/rails_info/logs.rb +2 -0
  56. data/lib/rails_info/logs/server.rb +230 -0
  57. data/lib/rails_info/logs/test.rb +2 -0
  58. data/lib/rails_info/logs/test/rspec.rb +160 -0
  59. data/lib/rails_info/model.rb +221 -0
  60. data/lib/rails_info/stack_trace.rb +155 -0
  61. data/lib/rails_info/version.rb +3 -0
  62. data/lib/tasks/rails_info_tasks.rake +4 -0
  63. data/spec/dummy/README.rdoc +261 -0
  64. data/spec/dummy/Rakefile +7 -0
  65. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  66. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  67. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  68. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  69. data/spec/dummy/app/models/user.rb +3 -0
  70. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  71. data/spec/dummy/config.ru +4 -0
  72. data/spec/dummy/config/application.rb +59 -0
  73. data/spec/dummy/config/boot.rb +10 -0
  74. data/spec/dummy/config/database.yml +42 -0
  75. data/spec/dummy/config/environment.rb +5 -0
  76. data/spec/dummy/config/environments/development.rb +39 -0
  77. data/spec/dummy/config/environments/production.rb +69 -0
  78. data/spec/dummy/config/environments/test.rb +39 -0
  79. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  80. data/spec/dummy/config/initializers/inflections.rb +15 -0
  81. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  82. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  83. data/spec/dummy/config/initializers/session_store.rb +8 -0
  84. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  85. data/spec/dummy/config/locales/en.yml +5 -0
  86. data/spec/dummy/config/routes.rb +2 -0
  87. data/spec/dummy/log/development.log +4876 -0
  88. data/spec/dummy/public/404.html +26 -0
  89. data/spec/dummy/public/422.html +26 -0
  90. data/spec/dummy/public/500.html +25 -0
  91. data/spec/dummy/public/favicon.ico +0 -0
  92. data/spec/dummy/script/rails +6 -0
  93. metadata +274 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
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.
@@ -0,0 +1,58 @@
1
+ = RailsInfo
2
+
3
+ Wiki[https://github.com/applicat/rails_info/wiki]
4
+
5
+ Experimental engine for a rails application besides admin and continous integration web interface which extends standard /rails/info (properties through public.html iframe and on Rails 3 Edge / Rails 4 also the routes action) about some extra information resources in development environment.
6
+
7
+ It should be the place for other rake commands besides "rake routes" such as brakeman or best practices.
8
+
9
+ Prepare for sporadic Ruby segmentation faults caused by the Python powered syntax highlighter pygments in the early stages of this project (at least under Ruby 1.9.3 & Rails 3.2.6 on MacOS).
10
+ There will be a configuration option for deactivating syntax highlighting soon for the time being without a solution for this problem.
11
+
12
+ Tested on MacOS with: Rails 3.1 & Ruby 1.9.2, Rails 3.2.6 & Ruby 1.9.3.
13
+
14
+ == Installation
15
+
16
+ In <b>Rails 3</b>, add this under your development group to the Gemfile of your Rails 3 application and run the +bundle+ command.
17
+
18
+ gem "rails_info"
19
+
20
+ == Getting Started
21
+
22
+ === 1) Request the Web interface
23
+
24
+ Just start your Rails 3 application server and request the following page in your browser.
25
+
26
+ http://localhost:3001/rails/info
27
+
28
+ === 2) Custom Exception Stack Trace View
29
+
30
+ Add the following line at the top of your ApplicationController to replace the standard stack trace view by a customized version which displays the code snippet for each file of the stack trace inline:
31
+
32
+ include RailsInfo::Controller::ExceptionDiagnostics
33
+
34
+ Consider those sporadic Ruby segmentation faults mentioned above when you include this line ;-)
35
+
36
+ === 3) RSpec Log
37
+
38
+ Write the result of an rspec command to log/rspec.log
39
+
40
+ bundle exec rspec spec/whatever_you_want > log/rspec.log
41
+
42
+ Run your rails development server if not already started and request the following page:
43
+
44
+ http://localhost:3000/rails/info/logs/test/rspec
45
+
46
+ == Wiki Docs
47
+
48
+ * TODO
49
+
50
+ == Contribution
51
+
52
+ Just follow the screencast of Ryan Bates on railscasts.com:
53
+
54
+ http://railscasts.com/episodes/300-contributing-to-open-source
55
+
56
+ == License
57
+
58
+ This project uses MIT-LICENSE.
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'RailsInfo'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+
40
+ task :default => :test
@@ -0,0 +1,6 @@
1
+ //= require jquery
2
+ //= require jquery.ui.all
3
+ //= require jquery_ujs
4
+ //= require twitter/bootstrap
5
+ //= require ./base
6
+ //= require ./bootstrap
@@ -0,0 +1,6 @@
1
+ $(document).ready ->
2
+ $( ".accordions" ).each (k, v) ->
3
+ $(v).accordion({ autoHeight: false });
4
+
5
+ $(".tabs").each (k, v) ->
6
+ $(v).tabs({ autoHeight: false });
@@ -0,0 +1,4 @@
1
+ jQuery ->
2
+ $("a[rel=popover]").popover()
3
+ $(".tooltip").tooltip()
4
+ $("a[rel=tooltip]").tooltip()
@@ -0,0 +1,14 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require 'rails_info/bootstrap_and_overrides'
13
+ *= require 'rails_info/base'
14
+ */
@@ -0,0 +1,22 @@
1
+ /*
2
+ *= require jquery.ui.all
3
+ */
4
+
5
+ /*body {
6
+ font-family: Arial;
7
+ }*/
8
+
9
+ .ui-widget {
10
+ font-family: Arial;
11
+ font-size: 10px;
12
+ }
13
+
14
+ html, body, div, span {
15
+ font-family: Arial;
16
+ font-size: 10px;
17
+ }
18
+
19
+ .nav a {
20
+ font-family: Arial;
21
+ font-size: 10px;
22
+ }
@@ -0,0 +1,63 @@
1
+ @import "twitter/bootstrap/bootstrap";
2
+ /*body {
3
+ padding-top: 60px;
4
+ padding-left: 20px;
5
+ }*/
6
+
7
+ @import "twitter/bootstrap/responsive";
8
+
9
+ pre {
10
+ background-color: white;
11
+ border: 0px;
12
+ border-radius: 0px;
13
+ display: block;
14
+ font-size: 10px;
15
+ line-height: 18px;
16
+ margin: 0px;
17
+ padding: 0px;
18
+ white-space: pre-wrap;
19
+ word-wrap: break-word;
20
+ }
21
+
22
+ code, pre {
23
+ font-family: Arial;
24
+ }
25
+
26
+ code {
27
+ border-radius: 0px;
28
+ border-width: 0px;
29
+ color: black;
30
+ background-color: white;
31
+ font-size: 10px;
32
+ padding: 0px;
33
+ }
34
+
35
+ .nav a {
36
+ font-size:14px ! important;
37
+ }
38
+
39
+ // Set the correct sprite paths
40
+ @iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
41
+ @iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');
42
+
43
+ // Set the Font Awesome (Font Awesome is default. You can disable by commenting below lines)
44
+ // Note: If you use asset_path() here, your compiled boostrap_and_overrides.css will not
45
+ // have the proper paths. So for now we use the absolute path.
46
+ @fontAwesomeEotPath: '/assets/fontawesome-webfont.eot';
47
+ @fontAwesomeWoffPath: '/assets/fontawesome-webfont.woff';
48
+ @fontAwesomeTtfPath: '/assets/fontawesome-webfont.ttf';
49
+ @fontAwesomeSvgPath: '/assets/fontawesome-webfont.svg';
50
+
51
+ // Font Awesome
52
+ @import "fontawesome";
53
+
54
+ // Your custom LESS stylesheets goes here
55
+ //
56
+ // Since bootstrap was imported above you have access to its mixins which
57
+ // you may use and inherit here
58
+ //
59
+ // If you'd like to override bootstrap's own variables, you can do so here as well
60
+ // See http://twitter.github.com/bootstrap/less.html for their names and documentation
61
+ //
62
+ // Example:
63
+ // @linkColor: #ff0000;
@@ -0,0 +1,17 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require jquery.ui.all
13
+ *= require rails_info/bootstrap_and_overrides
14
+ *= require rails_info/base
15
+ *= require rails_info/exception/base
16
+ *= require rails_info/exception/pygments
17
+ */
@@ -0,0 +1,31 @@
1
+ table {
2
+ padding: 0px; margin:0px;
3
+ font-family: Arial;
4
+ border: 1px solid black;
5
+ border-collapse: collapse;
6
+ }
7
+
8
+ td {
9
+ padding: 0px 5px;
10
+ margin: 0px;
11
+ border: 1px solid black;
12
+ vertical-align:top;
13
+ }
14
+
15
+ td.number {
16
+ font-size: 12px;
17
+ vertical-align:bottom;
18
+ }
19
+
20
+ pre {
21
+ font-size:14px;
22
+ display: inline;
23
+ }
24
+
25
+ pre.stack_trace_message {
26
+ display: block;
27
+ background-color: #EEEEEE;
28
+ font-size: 11px;
29
+ padding: 10px;
30
+ white-space: pre-wrap;
31
+ }
@@ -0,0 +1,5 @@
1
+ <%= Pygments.css(style: "colorful") %>
2
+
3
+ .hll, .hll span {
4
+ background-color: #FFFFCC ! important;
5
+ }
@@ -0,0 +1,9 @@
1
+ class RailsInfo::DataController < RailsInfoController
2
+ def index
3
+ @rails_info_data = ::RailsInfo::DataPresenter.new(view_context)
4
+ end
5
+
6
+ def update_multiple_data
7
+ RailsInfo::Data.update_multiple_data(params[:data]) if params[:delete]
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class RailsInfo::Logs::ServerController < RailsInfoController
2
+ def new
3
+ @rails_info_log = ::RailsInfo::Logs::ServerPresenter.new(view_context, log: params[:log], debug: params[:debug])
4
+ end
5
+
6
+ def update
7
+ @rails_info_log = ::RailsInfo::Logs::ServerPresenter.new(log: params[:log], debug: params[:debug])
8
+ render 'new'
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ class RailsInfo::Logs::Test::RspecController < RailsInfoController
2
+ layout 'rails_info/exception'
3
+
4
+ def new
5
+ @rails_info_log = ::RailsInfo::Logs::Test::RspecPresenter.new(
6
+ view_context, log: {rails_root: Rails.root.to_s}.merge(params[:log] || {}), debug: params[:debug]
7
+ )
8
+ end
9
+
10
+ def update
11
+ @rails_info_log = ::RailsInfo::Logs::Test::RspecPresenter.new(
12
+ view_context, log: params[:log], debug: params[:debug]
13
+ )
14
+ render 'new'
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class RailsInfo::ModelController < RailsInfoController
2
+ def index
3
+ @rails_info_model = ::RailsInfo::ModelPresenter.new(view_context)
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ class RailsInfo::PropertiesController < RailsInfoController
2
+ def index
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ class RailsInfo::RoutesController < RailsInfoController
2
+ def index
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ class RailsInfo::StackTracesController < RailsInfoController
2
+ layout 'rails_info/exception'
3
+
4
+ def new
5
+ end
6
+
7
+ def create
8
+ @stack_trace = RailsInfo::StackTracePresenter.new(view_context, stack_trace: params[:stack_trace])
9
+ render 'new'
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ class RailsInfoController < Rails::InfoController
2
+ include ::RailsInfo::Controller::ExceptionDiagnostics
3
+
4
+ before_filter :check_if_all_requests_local
5
+
6
+ #TODO: should inherit from ApplicationController especially for authentification & authorization purposes
7
+ layout 'rails_info'
8
+
9
+ private
10
+
11
+ def check_if_all_requests_local
12
+ unless Rails.application.config.consider_all_requests_local || request.local?
13
+ render text: '<p>For security purposes, this information is only available to local requests.</p>', status: :forbidden
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,194 @@
1
+ module RailsInfo::ResourcesHelper
2
+ TRANSLATED_COLUMNS = []
3
+
4
+ def resource_tree(presenter, parent_id = '')
5
+ content = ""
6
+
7
+ presenter.each do |title, resource_presenter|
8
+ id = parent_id.blank? ? title.parameterize : "#{parent_id}-#{title.parameterize}"
9
+
10
+ if resource_presenter[:sub_collection]
11
+ content += content_tag(:li, raw(title) + resource_tree(resource_presenter[:sub_collection], id))
12
+ else
13
+ content += content_tag(:li, title)
14
+ end
15
+ end
16
+
17
+ content_tag(:ul, raw(content))
18
+ end
19
+
20
+ def resource_presenter_renderer(presenter)
21
+ params['display_type'] == 'flat' ? raw(flat_resource_presenter_renderer(presenter)) : nested_resource_presenter_renderer(presenter)
22
+ end
23
+
24
+ def nested_resource_presenter_renderer(presenter, parent_id = '')
25
+ tabs_for do |tab|
26
+ presenter.each do |title,resource_presenter|
27
+ id = parent_id.blank? ? title.parameterize : "#{parent_id}-#{title.parameterize}"
28
+ tab_title = resource_presenter[:group_by] ? "#{title} (Group by: #{resource_presenter[:group_by]})" : title
29
+ tab.create(id, tab_title) do
30
+ content = ""
31
+
32
+ resource_presenter[:collection] = [resource_presenter[:collection]] unless resource_presenter[:collection].respond_to?('first')
33
+
34
+ if resource_presenter[:collection]
35
+ content = render(
36
+ 'shared/resource/section', {
37
+ :title => title, :collection => resource_presenter[:collection], :group_by => resource_presenter[:group_by],
38
+ :group_by_values => resource_presenter[:group_by_values]
39
+ }
40
+ )
41
+ end
42
+
43
+ content += nested_resource_presenter_renderer(resource_presenter[:sub_collection], id) if resource_presenter[:sub_collection]
44
+
45
+ raw content
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def flat_resource_presenter_renderer(presenter, level = '')
52
+ content = ""
53
+
54
+ presenter.each do |title,resource_presenter|
55
+ content += render('shared/resource/section', :title => "#{level} #{title}", :collection => resource_presenter[:collection]) if resource_presenter[:collection]
56
+
57
+ content += flat_resource_presenter_renderer(resource_presenter[:sub_collection], "#{level} -") if resource_presenter[:sub_collection]
58
+ end
59
+
60
+ content
61
+ end
62
+
63
+ def collection_map(collection_map)
64
+ collection = []
65
+
66
+ collection_map.each do |sub_collection|
67
+ sub_collection.each do |resource|
68
+ collection << resource
69
+ end
70
+ end
71
+
72
+ collection_map.clear
73
+
74
+ collection
75
+ end
76
+
77
+ def grouped_collection(title, collection, group_by)
78
+ @grouped_collections ||= {}
79
+
80
+ collection_key = "#{title}-{group_by}-#{collection.length}"
81
+
82
+ return @grouped_collections[collection_key] if @grouped_collections[collection_key]
83
+
84
+ @grouped_collections[collection_key] = ActiveSupport::OrderedHash.new
85
+
86
+ collection.each do |element|
87
+ if element.is_a?(Hash)
88
+ key = element[group_by.to_s]
89
+ elsif element.respond_to?('translation') && element.translation.respond_to?(group_by)
90
+ key = element.translation.send(group_by)
91
+ else
92
+ key = element.send(group_by)
93
+ end
94
+
95
+ if @grouped_collections[collection_key].has_key?(key)
96
+ @grouped_collections[collection_key][key] << element
97
+ else
98
+ @grouped_collections[collection_key][key] = [element]
99
+ end
100
+ end
101
+
102
+ @grouped_collections[collection_key]
103
+ end
104
+
105
+ def group_columns(title, collection, group_by = nil, group_by_values = nil)
106
+ collection_columns = grouped_collection(title, collection, group_by).keys
107
+
108
+ if group_by_values.is_a?(Array)
109
+ group_by_values.delete_if {|c| !collection_columns.include?(c) }
110
+ collection_columns.delete_if {|c| group_by_values.include?(c) }
111
+ group_by_values + collection_columns
112
+ else
113
+ collection_columns
114
+ end
115
+ end
116
+
117
+ def resource_columns(collection, group_by = nil)
118
+ collection_columns = []
119
+
120
+ if collection.first.is_a?(Array)
121
+ raise "Please wrap the :collection by help.collection_map: #{collection.inspect}"
122
+ elsif collection.first.is_a?(Hash)
123
+ collection_columns = collection.first[:class].columns.map(&:name)
124
+ else
125
+ collection_columns = collection.first.attributes.keys
126
+ end
127
+
128
+ exclude_columns = [
129
+ 'current_code', 'last_code' # WorkflowControllerType binary columns
130
+ ]
131
+
132
+ exclude_columns << group_by if group_by
133
+
134
+ collection_columns.delete_if {|c| exclude_columns.include?(c) }
135
+
136
+ unless collection.first.is_a?(Hash)
137
+ TRANSLATED_COLUMNS.each do |translated_column|
138
+ if !collection.first.attributes[translated_column] && collection.first.respond_to?('translation') && collection.first.translation.respond_to?(translated_column)
139
+ collection_columns << translated_column
140
+ end
141
+ end
142
+ end
143
+
144
+ first_columns = ['id', 'sort_order', 'order', 'position', 'type', 'state', 'name', 'label', 'title', 'slug']
145
+ first_columns.delete_if {|c| !collection_columns.include?(c) }
146
+ collection_columns.delete_if {|c| first_columns.include?(c) }
147
+
148
+ bool_columns = ['final' ,'public', 'hidden']
149
+ bool_columns.delete_if {|c| !collection_columns.include?(c) }
150
+ collection_columns.delete_if {|c| bool_columns.include?(c) }
151
+
152
+ able_columns = collection_columns.select {|v| v.match('able') }
153
+ collection_columns.delete_if {|c| able_columns.include?(c) }
154
+
155
+ is_columns = collection_columns.select {|v| v.match('is_') }
156
+ collection_columns.delete_if {|c| is_columns.include?(c) }
157
+
158
+ id_columns = collection_columns.select {|v| v.match('_id') || v.match('_type') }
159
+ collection_columns.delete_if {|c| id_columns.include?(c) }
160
+
161
+ at_columns = collection_columns.select {|v| v.match('_at') }
162
+ collection_columns.delete_if {|c| at_columns.include?(c) }
163
+
164
+ last_columns = []
165
+ last_columns.delete_if {|c| !collection_columns.include?(c) }
166
+ collection_columns.delete_if {|c| last_columns.include?(c) }
167
+
168
+ standard_rails_timestamps = ['created_at', 'updated_at']
169
+ standard_rails_timestamps.delete_if {|c| !at_columns.include?(c) }
170
+ at_columns.delete_if {|c| at_columns.include?(c) }
171
+
172
+ content_for :columns_order, "first_columns + collection_columns + bool_columns + able_columns + is_columns + id_columns + at_columns + last_columns + standard_rails_timestamps" unless content_for?(:columns_order)
173
+
174
+ first_columns + collection_columns + bool_columns + able_columns + is_columns + id_columns + at_columns + last_columns + standard_rails_timestamps
175
+ end
176
+
177
+ def resource_cell(row, column)
178
+ if row.is_a?(Hash)
179
+ return "" unless row.has_key?(column)
180
+
181
+ content = row[column].to_s
182
+ else
183
+ return "" unless row.respond_to?(column)
184
+
185
+ content = row.send(column).to_s
186
+ end
187
+
188
+ truncate_length = params['truncate_length'] ? params['truncate_length'].to_i : 50
189
+
190
+ content = content_tag(:span, truncate(raw(content), :length => truncate_length), :title => content) if content.length > truncate_length
191
+
192
+ content
193
+ end
194
+ end