rails_info 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.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +58 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/rails_info/application.js +6 -0
- data/app/assets/javascripts/rails_info/base.js.coffee +6 -0
- data/app/assets/javascripts/rails_info/bootstrap.js.coffee +4 -0
- data/app/assets/stylesheets/rails_info/application.css +14 -0
- data/app/assets/stylesheets/rails_info/base.css.scss +22 -0
- data/app/assets/stylesheets/rails_info/bootstrap_and_overrides.css.less +63 -0
- data/app/assets/stylesheets/rails_info/exception.css +17 -0
- data/app/assets/stylesheets/rails_info/exception/base.css.scss +31 -0
- data/app/assets/stylesheets/rails_info/exception/pygments.css.erb +5 -0
- data/app/controllers/rails_info/data_controller.rb +9 -0
- data/app/controllers/rails_info/logs/server_controller.rb +10 -0
- data/app/controllers/rails_info/logs/test/rspec_controller.rb +16 -0
- data/app/controllers/rails_info/model_controller.rb +5 -0
- data/app/controllers/rails_info/properties_controller.rb +4 -0
- data/app/controllers/rails_info/routes_controller.rb +4 -0
- data/app/controllers/rails_info/stack_traces_controller.rb +11 -0
- data/app/controllers/rails_info_controller.rb +16 -0
- data/app/helpers/rails_info/resources_helper.rb +194 -0
- data/app/presenters/rails_info/code_presenter.rb +63 -0
- data/app/presenters/rails_info/data/object_presenter.rb +34 -0
- data/app/presenters/rails_info/data/row_set_presenter.rb +38 -0
- data/app/presenters/rails_info/data_presenter.rb +21 -0
- data/app/presenters/rails_info/logs/server/action_presenter.rb +109 -0
- data/app/presenters/rails_info/logs/server_presenter.rb +57 -0
- data/app/presenters/rails_info/logs/test/rspec/file_presenter.rb +87 -0
- data/app/presenters/rails_info/logs/test/rspec_presenter.rb +32 -0
- data/app/presenters/rails_info/model_presenter.rb +68 -0
- data/app/presenters/rails_info/presenter.rb +19 -0
- data/app/presenters/rails_info/stack_trace_presenter.rb +98 -0
- data/app/views/layouts/_layout.html.erb +19 -0
- data/app/views/layouts/rails_info.html.erb +1 -0
- data/app/views/layouts/rails_info/exception.html.erb +1 -0
- data/app/views/layouts/shared/_navigation.html.erb +7 -0
- data/app/views/rails_info/data/index.html.erb +23 -0
- data/app/views/rails_info/logs/server/_table.html.erb +16 -0
- data/app/views/rails_info/logs/server/new.html.erb +19 -0
- data/app/views/rails_info/logs/test/rspec/new.html.erb +10 -0
- data/app/views/rails_info/model/index.html.erb +14 -0
- data/app/views/rails_info/properties/index.html.erb +1 -0
- data/app/views/rails_info/routes/index.html.erb +18 -0
- data/app/views/rails_info/stack_traces/_accordion.html.erb +1 -0
- data/app/views/rails_info/stack_traces/_form.html.erb +11 -0
- data/app/views/rails_info/stack_traces/_with_request_and_response.html.erb +16 -0
- data/app/views/rails_info/stack_traces/new.html.erb +10 -0
- data/config/navigation.rb +20 -0
- data/config/routes.rb +20 -0
- data/lib/rails_info.rb +19 -0
- data/lib/rails_info/controller.rb +2 -0
- data/lib/rails_info/controller/exception_diagnostics.rb +28 -0
- data/lib/rails_info/data.rb +55 -0
- data/lib/rails_info/engine.rb +9 -0
- data/lib/rails_info/logs.rb +2 -0
- data/lib/rails_info/logs/server.rb +230 -0
- data/lib/rails_info/logs/test.rb +2 -0
- data/lib/rails_info/logs/test/rspec.rb +160 -0
- data/lib/rails_info/model.rb +221 -0
- data/lib/rails_info/stack_trace.rb +155 -0
- data/lib/rails_info/version.rb +3 -0
- data/lib/tasks/rails_info_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +59 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +42 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +39 -0
- data/spec/dummy/config/environments/production.rb +69 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/log/development.log +4876 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- metadata +274 -0
data/MIT-LICENSE
ADDED
|
@@ -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.
|
data/README.rdoc
ADDED
|
@@ -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.
|
data/Rakefile
ADDED
|
@@ -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,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,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,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
|