typus 0.9.17
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/.gitignore +8 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +86 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/app/controllers/admin/master_controller.rb +354 -0
- data/app/controllers/typus_controller.rb +128 -0
- data/app/helpers/admin/form_helper.rb +386 -0
- data/app/helpers/admin/master_helper.rb +104 -0
- data/app/helpers/admin/public_helper.rb +27 -0
- data/app/helpers/admin/sidebar_helper.rb +236 -0
- data/app/helpers/admin/table_helper.rb +227 -0
- data/app/helpers/typus_helper.rb +194 -0
- data/app/models/typus_mailer.rb +14 -0
- data/app/models/typus_user.rb +5 -0
- data/app/views/admin/dashboard/_sidebar.html.erb +9 -0
- data/app/views/admin/resources/edit.html.erb +24 -0
- data/app/views/admin/resources/index.html.erb +23 -0
- data/app/views/admin/resources/new.html.erb +22 -0
- data/app/views/admin/resources/show.html.erb +18 -0
- data/app/views/admin/shared/_footer.html.erb +1 -0
- data/app/views/admin/shared/_pagination.html.erb +28 -0
- data/app/views/layouts/admin.html.erb +73 -0
- data/app/views/layouts/typus.html.erb +29 -0
- data/app/views/typus/dashboard.html.erb +9 -0
- data/app/views/typus/recover_password.html.erb +7 -0
- data/app/views/typus/reset_password.html.erb +15 -0
- data/app/views/typus/sign_in.html.erb +9 -0
- data/app/views/typus/sign_up.html.erb +7 -0
- data/app/views/typus_mailer/reset_password_link.erb +11 -0
- data/config/locales/typus/de.yml +109 -0
- data/config/locales/typus/es.yml +109 -0
- data/config/locales/typus/language.yml.template +113 -0
- data/config/locales/typus/pt-BR.yml +111 -0
- data/config/locales/typus/ru.yml +111 -0
- data/generators/typus/templates/config/initializers/typus.rb +33 -0
- data/generators/typus/templates/config/typus/README +51 -0
- data/generators/typus/templates/config/typus/application.yml +6 -0
- data/generators/typus/templates/config/typus/application_roles.yml +23 -0
- data/generators/typus/templates/config/typus/typus.yml +14 -0
- data/generators/typus/templates/config/typus/typus_roles.yml +2 -0
- data/generators/typus/templates/db/create_typus_users.rb +21 -0
- data/generators/typus/templates/public/images/admin/arrow_down.gif +0 -0
- data/generators/typus/templates/public/images/admin/arrow_up.gif +0 -0
- data/generators/typus/templates/public/images/admin/spinner.gif +0 -0
- data/generators/typus/templates/public/images/admin/status_false.gif +0 -0
- data/generators/typus/templates/public/images/admin/status_true.gif +0 -0
- data/generators/typus/templates/public/images/admin/trash.gif +0 -0
- data/generators/typus/templates/public/javascripts/admin/application.js +14 -0
- data/generators/typus/templates/public/stylesheets/admin/reset.css +68 -0
- data/generators/typus/templates/public/stylesheets/admin/screen.css +729 -0
- data/generators/typus/typus_generator.rb +122 -0
- data/generators/typus_update_schema_to_01/templates/config/typus.yml +14 -0
- data/generators/typus_update_schema_to_01/templates/migration.rb +11 -0
- data/generators/typus_update_schema_to_01/typus_update_schema_to_01_generator.rb +19 -0
- data/lib/typus.rb +122 -0
- data/lib/typus/active_record.rb +307 -0
- data/lib/typus/authentication.rb +142 -0
- data/lib/typus/configuration.rb +85 -0
- data/lib/typus/extensions/routes.rb +15 -0
- data/lib/typus/format.rb +55 -0
- data/lib/typus/generator.rb +81 -0
- data/lib/typus/hash.rb +8 -0
- data/lib/typus/locale.rb +17 -0
- data/lib/typus/object.rb +21 -0
- data/lib/typus/quick_edit.rb +40 -0
- data/lib/typus/reloader.rb +15 -0
- data/lib/typus/string.rb +11 -0
- data/lib/typus/templates/index.html.erb +11 -0
- data/lib/typus/templates/resource_controller.rb.erb +15 -0
- data/lib/typus/templates/resource_controller_test.rb.erb +10 -0
- data/lib/typus/templates/resources_controller.rb.erb +37 -0
- data/lib/typus/user.rb +134 -0
- data/lib/vendor/active_record.rb +15 -0
- data/lib/vendor/paginator.rb +143 -0
- data/rails/init.rb +3 -0
- data/tasks/typus_tasks.rake +32 -0
- data/test/config/broken/application.yml +68 -0
- data/test/config/broken/application_roles.yml +20 -0
- data/test/config/broken/empty.yml +0 -0
- data/test/config/broken/empty_roles.yml +0 -0
- data/test/config/broken/undefined.yml +3 -0
- data/test/config/broken/undefined_roles.yml +6 -0
- data/test/config/default/typus.yml +14 -0
- data/test/config/default/typus_roles.yml +2 -0
- data/test/config/empty/empty_01.yml +0 -0
- data/test/config/empty/empty_01_roles.yml +0 -0
- data/test/config/empty/empty_02.yml +0 -0
- data/test/config/empty/empty_02_roles.yml +0 -0
- data/test/config/locales/es.yml +10 -0
- data/test/config/ordered/001_roles.yml +2 -0
- data/test/config/ordered/002_roles.yml +2 -0
- data/test/config/unordered/app_one_roles.yml +2 -0
- data/test/config/unordered/app_two_roles.yml +2 -0
- data/test/config/working/application.yml +68 -0
- data/test/config/working/application_roles.yml +22 -0
- data/test/config/working/typus.yml +14 -0
- data/test/config/working/typus_roles.yml +2 -0
- data/test/fixtures/app/controllers/admin/assets_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/categories_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/comments_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/pages_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/posts_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/status_controller.rb +6 -0
- data/test/fixtures/app/controllers/admin/typus_users_controller.rb +2 -0
- data/test/fixtures/app/controllers/admin/watch_dog_controller.rb +6 -0
- data/test/fixtures/app/views/admin/comments/_edit.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_index.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_new.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_show.html.erb +1 -0
- data/test/fixtures/app/views/admin/comments/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_content.html.erb +1 -0
- data/test/fixtures/app/views/admin/dashboard/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/resources/_sidebar.html.erb +1 -0
- data/test/fixtures/app/views/admin/shared/_footer.html.erb +1 -0
- data/test/fixtures/app/views/admin/status/index.html.erb +1 -0
- data/test/fixtures/app/views/admin/templates/_datepicker.html.erb +1 -0
- data/test/fixtures/assets.yml +11 -0
- data/test/fixtures/categories.yml +14 -0
- data/test/fixtures/comments.yml +27 -0
- data/test/fixtures/pages.yml +41 -0
- data/test/fixtures/posts.yml +37 -0
- data/test/fixtures/typus_users.yml +54 -0
- data/test/functional/admin/assets_controller_test.rb +57 -0
- data/test/functional/admin/categories_controller_test.rb +106 -0
- data/test/functional/admin/comments_controller_test.rb +120 -0
- data/test/functional/admin/master_controller_test.rb +5 -0
- data/test/functional/admin/posts_controller_test.rb +261 -0
- data/test/functional/admin/status_controller_test.rb +43 -0
- data/test/functional/admin/typus_users_controller_test.rb +239 -0
- data/test/functional/typus_controller_test.rb +321 -0
- data/test/helper.rb +51 -0
- data/test/helpers/admin/form_helper_test.rb +337 -0
- data/test/helpers/admin/master_helper_test.rb +69 -0
- data/test/helpers/admin/public_helper_test.rb +26 -0
- data/test/helpers/admin/sidebar_helper_test.rb +335 -0
- data/test/helpers/admin/table_helper_test.rb +239 -0
- data/test/helpers/typus_helper_test.rb +117 -0
- data/test/lib/active_record_test.rb +382 -0
- data/test/lib/configuration_test.rb +94 -0
- data/test/lib/hash_test.rb +11 -0
- data/test/lib/routes_test.rb +71 -0
- data/test/lib/string_test.rb +25 -0
- data/test/lib/typus_test.rb +85 -0
- data/test/models.rb +51 -0
- data/test/schema.rb +64 -0
- data/test/unit/typus_mailer_test.rb +33 -0
- data/test/unit/typus_test.rb +17 -0
- data/test/unit/typus_user_roles_test.rb +90 -0
- data/test/unit/typus_user_test.rb +177 -0
- data/test/vendor/active_record_test.rb +18 -0
- data/test/vendor/paginator_test.rb +136 -0
- data/typus.gemspec +228 -0
- metadata +241 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
module Admin::MasterHelper
|
|
2
|
+
|
|
3
|
+
include TypusHelper
|
|
4
|
+
|
|
5
|
+
include Admin::SidebarHelper
|
|
6
|
+
include Admin::FormHelper
|
|
7
|
+
include Admin::TableHelper
|
|
8
|
+
|
|
9
|
+
def display_link_to_previous # (_params = params)
|
|
10
|
+
|
|
11
|
+
options = {}
|
|
12
|
+
options[:resource_from] = @resource[:class].typus_human_name
|
|
13
|
+
options[:resource_to] = params[:resource].classify.humanize if params[:resource]
|
|
14
|
+
|
|
15
|
+
editing = %w( edit update ).include?(params[:action])
|
|
16
|
+
|
|
17
|
+
message = case
|
|
18
|
+
when params[:resource] && editing
|
|
19
|
+
_("You're updating a {{resource_from}} for {{resource_to}}.",
|
|
20
|
+
:resource_from => options[:resource_from],
|
|
21
|
+
:resource_to => options[:resource_to])
|
|
22
|
+
when editing
|
|
23
|
+
_("You're updating a {{resource_from}}.",
|
|
24
|
+
:resource_from => options[:resource_from])
|
|
25
|
+
when params[:resource]
|
|
26
|
+
_("You're adding a new {{resource_from}} to {{resource_to}}.",
|
|
27
|
+
:resource_from => options[:resource_from],
|
|
28
|
+
:resource_to => options[:resource_to])
|
|
29
|
+
else
|
|
30
|
+
_("You're adding a new {{resource_from}}.",
|
|
31
|
+
:resource_from => options[:resource_from] )
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
returning(String.new) do |html|
|
|
35
|
+
html << <<-HTML
|
|
36
|
+
<div id="flash" class="notice">
|
|
37
|
+
<p>#{message} #{link_to _("Do you want to cancel it?"), params[:back_to]}</p>
|
|
38
|
+
</div>
|
|
39
|
+
HTML
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def remove_filter_link(filter = request.env['QUERY_STRING'])
|
|
45
|
+
return unless filter && !filter.blank?
|
|
46
|
+
<<-HTML
|
|
47
|
+
<small>#{link_to _("Remove filter")}</small>
|
|
48
|
+
HTML
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# If there's a partial with a "microformat" of the data we want to
|
|
53
|
+
# display, this will be used, otherwise we use a default table which
|
|
54
|
+
# it's build from the options defined on the yaml configuration file.
|
|
55
|
+
#
|
|
56
|
+
def build_list(model, fields, items, resource = @resource[:self], link_options = {}, association = nil)
|
|
57
|
+
|
|
58
|
+
template = "app/views/admin/#{resource}/_#{resource.singularize}.html.erb"
|
|
59
|
+
|
|
60
|
+
if File.exist?(template)
|
|
61
|
+
render :partial => template.gsub('/_', '/'), :collection => items, :as => :item
|
|
62
|
+
else
|
|
63
|
+
build_typus_table(model, fields, items, link_options, association)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def pagination(*args)
|
|
69
|
+
@options = args.extract_options!
|
|
70
|
+
render 'admin/shared/pagination' if @items.prev || @items.next
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# Simple and clean pagination links
|
|
75
|
+
#
|
|
76
|
+
def build_pagination(pager, options = {})
|
|
77
|
+
|
|
78
|
+
options[:link_to_current_page] ||= true
|
|
79
|
+
options[:always_show_anchors] ||= true
|
|
80
|
+
|
|
81
|
+
# Calculate the window start and end pages
|
|
82
|
+
options[:padding] ||= 2
|
|
83
|
+
options[:padding] = options[:padding] < 0 ? 0 : options[:padding]
|
|
84
|
+
|
|
85
|
+
page = params[:page].blank? ? 1 : params[:page].to_i
|
|
86
|
+
current_page = pager.page(page)
|
|
87
|
+
|
|
88
|
+
first = pager.first.number <= (current_page.number - options[:padding]) && pager.last.number >= (current_page.number - options[:padding]) ? current_page.number - options[:padding] : 1
|
|
89
|
+
last = pager.first.number <= (current_page.number + options[:padding]) && pager.last.number >= (current_page.number + options[:padding]) ? current_page.number + options[:padding] : pager.last.number
|
|
90
|
+
|
|
91
|
+
returning(String.new) do |html|
|
|
92
|
+
# Print start page if anchors are enabled
|
|
93
|
+
html << yield(1) if options[:always_show_anchors] and not first == 1
|
|
94
|
+
# Print window pages
|
|
95
|
+
first.upto(last) do |page|
|
|
96
|
+
(current_page.number == page && !options[:link_to_current_page]) ? html << page.to_s : html << (yield(page)).to_s
|
|
97
|
+
end
|
|
98
|
+
# Print end page if anchors are enabled
|
|
99
|
+
html << yield(pager.last.number).to_s if options[:always_show_anchors] and not last == pager.last.number
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Admin
|
|
2
|
+
|
|
3
|
+
module PublicHelper
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Quick edit usage:
|
|
7
|
+
#
|
|
8
|
+
# <%= quick_edit(:message => "Edit this article", :path => "articles/edit/#{@article.id}") %>
|
|
9
|
+
#
|
|
10
|
+
# If user is logged in Typus, a link will appear on the top/right of
|
|
11
|
+
# the pages where you insert this helper.
|
|
12
|
+
#
|
|
13
|
+
def quick_edit(*args)
|
|
14
|
+
|
|
15
|
+
options = args.extract_options!
|
|
16
|
+
|
|
17
|
+
<<-HTML
|
|
18
|
+
<script type="text/javascript">
|
|
19
|
+
document.write('<script type="text/javascript" src="#{admin_quick_edit_path}?#{options.to_query}" />');
|
|
20
|
+
</script>
|
|
21
|
+
HTML
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
module Admin::SidebarHelper
|
|
2
|
+
|
|
3
|
+
def actions
|
|
4
|
+
|
|
5
|
+
returning(String.new) do |html|
|
|
6
|
+
|
|
7
|
+
html << <<-HTML
|
|
8
|
+
#{build_typus_list(default_actions, :header => 'actions')}
|
|
9
|
+
#{build_typus_list(previous_and_next, :header => 'go_to')}
|
|
10
|
+
HTML
|
|
11
|
+
|
|
12
|
+
html << <<-HTML
|
|
13
|
+
#{build_typus_list(export, :header => 'export')}
|
|
14
|
+
HTML
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def default_actions
|
|
21
|
+
|
|
22
|
+
items = []
|
|
23
|
+
|
|
24
|
+
case params[:action]
|
|
25
|
+
when 'index', 'edit', 'show', 'update'
|
|
26
|
+
if @current_user.can_perform?(@resource[:class], 'create')
|
|
27
|
+
items << (link_to _("Add entry"), :action => 'new')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
case params[:action]
|
|
32
|
+
when 'show'
|
|
33
|
+
if @current_user.can_perform?(@resource[:class], 'update')
|
|
34
|
+
items << (link_to _("Edit entry"), :action => 'edit', :id => @item.id)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
@resource[:class].typus_actions_for(params[:action]).each do |action|
|
|
39
|
+
if @current_user.can_perform?(@resource[:class], action)
|
|
40
|
+
items << (link_to _(action.humanize), params.merge(:action => action))
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
case params[:action]
|
|
45
|
+
when 'new', 'create', 'edit', 'show', 'update'
|
|
46
|
+
items << (link_to _("Back to list"), :action => 'index')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
return items
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def export
|
|
54
|
+
return [] unless params[:action] == 'index'
|
|
55
|
+
returning(Array.new) do |format|
|
|
56
|
+
@resource[:class].typus_export_formats.each do |f|
|
|
57
|
+
format << (link_to f.upcase, params.merge(:format => f))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def build_typus_list(items, *args)
|
|
63
|
+
|
|
64
|
+
options = args.extract_options!
|
|
65
|
+
|
|
66
|
+
header = if options[:header]
|
|
67
|
+
_(options[:header].humanize)
|
|
68
|
+
elsif options[:attribute]
|
|
69
|
+
@resource[:class].human_attribute_name(options[:attribute])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
return String.new if items.empty?
|
|
73
|
+
returning(String.new) do |html|
|
|
74
|
+
html << "<h2>#{header}</h2>\n" unless header.nil?
|
|
75
|
+
next unless options[:selector].nil?
|
|
76
|
+
html << "<ul>\n"
|
|
77
|
+
items.each do |item|
|
|
78
|
+
html << "<li>#{item}</li>\n"
|
|
79
|
+
end
|
|
80
|
+
html << "</ul>\n"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def previous_and_next
|
|
86
|
+
return [] unless %w( edit show update ).include?(params[:action])
|
|
87
|
+
returning(Array.new) do |items|
|
|
88
|
+
items << (link_to _("Next"), params.merge(:id => @next.id)) if @next
|
|
89
|
+
items << (link_to _("Previous"), params.merge(:id => @previous.id)) if @previous
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def search
|
|
94
|
+
|
|
95
|
+
typus_search = @resource[:class].typus_defaults_for(:search)
|
|
96
|
+
return if typus_search.empty?
|
|
97
|
+
|
|
98
|
+
search_by = typus_search.collect { |x| @resource[:class].human_attribute_name(x) }.to_sentence
|
|
99
|
+
|
|
100
|
+
search_params = params.dup
|
|
101
|
+
%w( action controller search page ).each { |p| search_params.delete(p) }
|
|
102
|
+
|
|
103
|
+
hidden_params = search_params.map { |key, value| hidden_field_tag(key, value) }
|
|
104
|
+
|
|
105
|
+
<<-HTML
|
|
106
|
+
<h2>#{_("Search")}</h2>
|
|
107
|
+
<form action="" method="get">
|
|
108
|
+
<p><input id="search" name="search" type="text" value="#{params[:search]}"/></p>
|
|
109
|
+
#{hidden_params.sort.join("\n")}
|
|
110
|
+
</form>
|
|
111
|
+
<p class="tip">#{_("Search by")} #{search_by.downcase}.</p>
|
|
112
|
+
HTML
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def filters
|
|
117
|
+
|
|
118
|
+
typus_filters = @resource[:class].typus_filters
|
|
119
|
+
return if typus_filters.empty?
|
|
120
|
+
|
|
121
|
+
current_request = request.env['QUERY_STRING'] || []
|
|
122
|
+
|
|
123
|
+
returning(String.new) do |html|
|
|
124
|
+
typus_filters.each do |key, value|
|
|
125
|
+
case value
|
|
126
|
+
when :boolean then html << boolean_filter(current_request, key)
|
|
127
|
+
when :string then html << string_filter(current_request, key)
|
|
128
|
+
when :datetime then html << datetime_filter(current_request, key)
|
|
129
|
+
when :belongs_to then html << relationship_filter(current_request, key)
|
|
130
|
+
when :has_and_belongs_to_many then
|
|
131
|
+
html << relationship_filter(current_request, key, true)
|
|
132
|
+
else
|
|
133
|
+
html << "<p>#{_("Unknown")}</p>"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def relationship_filter(request, filter, habtm = false)
|
|
141
|
+
|
|
142
|
+
model = (habtm) ? filter.classify.constantize : filter.capitalize.camelize.constantize
|
|
143
|
+
related_fk = (habtm) ? filter : @resource[:class].reflect_on_association(filter.to_sym).primary_key_name
|
|
144
|
+
|
|
145
|
+
params_without_filter = params.dup
|
|
146
|
+
%w( controller action page ).each { |p| params_without_filter.delete(p) }
|
|
147
|
+
params_without_filter.delete(related_fk)
|
|
148
|
+
|
|
149
|
+
items = []
|
|
150
|
+
|
|
151
|
+
returning(String.new) do |html|
|
|
152
|
+
related_items = model.find(:all, :order => model.typus_order_by)
|
|
153
|
+
if related_items.size > model.typus_options_for(:sidebar_selector)
|
|
154
|
+
related_items.each do |item|
|
|
155
|
+
switch = request.include?("#{related_fk}=#{item.id}") ? 'selected' : ''
|
|
156
|
+
items << <<-HTML
|
|
157
|
+
<option #{switch} value="#{url_for params.merge(related_fk => item.id, :page => nil)}">#{item.typus_name}</option>
|
|
158
|
+
HTML
|
|
159
|
+
end
|
|
160
|
+
model_pluralized = model.name.downcase.pluralize
|
|
161
|
+
form = <<-HTML
|
|
162
|
+
<!-- Embedded JS -->
|
|
163
|
+
<script>
|
|
164
|
+
function surfto_#{model_pluralized}(form) {
|
|
165
|
+
var myindex = form.#{model_pluralized}.selectedIndex
|
|
166
|
+
if (form.#{model_pluralized}.options[myindex].value != "0") {
|
|
167
|
+
top.location.href = form.#{model_pluralized}.options[myindex].value;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
<!-- /Embedded JS -->
|
|
172
|
+
<form class="form" action="#"><p>
|
|
173
|
+
<select name="#{model_pluralized}" onChange="surfto_#{model_pluralized}(this.form)">
|
|
174
|
+
<option value="#{url_for params_without_filter}">#{_("filter by")} #{_(model.typus_human_name)}</option>
|
|
175
|
+
#{items.join("\n")}
|
|
176
|
+
</select>
|
|
177
|
+
</p></form>
|
|
178
|
+
HTML
|
|
179
|
+
else
|
|
180
|
+
related_items.each do |item|
|
|
181
|
+
switch = request.include?("#{related_fk}=#{item.id}") ? 'on' : 'off'
|
|
182
|
+
items << (link_to item.typus_name, params.merge(related_fk => item.id, :page => nil), :class => switch)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if form
|
|
187
|
+
html << build_typus_list(items, :attribute => filter, :selector => true)
|
|
188
|
+
html << form
|
|
189
|
+
else
|
|
190
|
+
html << build_typus_list(items, :attribute => filter)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
##
|
|
198
|
+
# Thinking in update datetime_filters to ...
|
|
199
|
+
#
|
|
200
|
+
# %w( today last_few_days last_7_days last_30_days )
|
|
201
|
+
#
|
|
202
|
+
# ... which are the ones used by 'exception_logger'.
|
|
203
|
+
#
|
|
204
|
+
def datetime_filter(request, filter)
|
|
205
|
+
items = []
|
|
206
|
+
%w( today past_7_days this_month this_year ).each do |timeline|
|
|
207
|
+
switch = request.include?("#{filter}=#{timeline}") ? 'on' : 'off'
|
|
208
|
+
options = { filter.to_sym => timeline, :page => nil }
|
|
209
|
+
items << (link_to _(timeline.humanize), params.merge(options), :class => switch)
|
|
210
|
+
end
|
|
211
|
+
build_typus_list(items, :attribute => filter)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def boolean_filter(request, filter)
|
|
215
|
+
items = []
|
|
216
|
+
@resource[:class].typus_boolean(filter).each do |key, value|
|
|
217
|
+
switch = request.include?("#{filter}=#{key}") ? 'on' : 'off'
|
|
218
|
+
options = { filter.to_sym => key, :page => nil }
|
|
219
|
+
items << (link_to _(value), params.merge(options), :class => switch)
|
|
220
|
+
end
|
|
221
|
+
build_typus_list(items, :attribute => filter)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def string_filter(request, filter)
|
|
225
|
+
values = @resource[:class].send(filter)
|
|
226
|
+
items = []
|
|
227
|
+
values.each do |item|
|
|
228
|
+
link_name, link_filter = (values.first.kind_of?(Array)) ? [ item.first, item.last ] : [ item, item ]
|
|
229
|
+
switch = request.include?("#{filter}=#{link_filter}") ? 'on' : 'off'
|
|
230
|
+
options = { filter.to_sym => link_filter, :page => nil }
|
|
231
|
+
items << (link_to link_name.capitalize, params.merge(options), :class => switch)
|
|
232
|
+
end
|
|
233
|
+
build_typus_list(items, :attribute => filter)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
end
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
module Admin::TableHelper
|
|
2
|
+
|
|
3
|
+
def build_typus_table(model, fields, items, link_options = {}, association = nil)
|
|
4
|
+
|
|
5
|
+
returning(String.new) do |html|
|
|
6
|
+
|
|
7
|
+
html << <<-HTML
|
|
8
|
+
<table class="typus">
|
|
9
|
+
HTML
|
|
10
|
+
|
|
11
|
+
html << typus_table_header(model, fields)
|
|
12
|
+
|
|
13
|
+
items.each do |item|
|
|
14
|
+
|
|
15
|
+
html << <<-HTML
|
|
16
|
+
<tr class="#{cycle('even', 'odd')}" id="item_#{item.id}">
|
|
17
|
+
HTML
|
|
18
|
+
|
|
19
|
+
fields.each do |key, value|
|
|
20
|
+
case value
|
|
21
|
+
when :boolean then html << typus_table_boolean_field(key, item)
|
|
22
|
+
when :datetime then html << typus_table_datetime_field(key, item, fields.keys.first, link_options)
|
|
23
|
+
when :date then html << typus_table_datetime_field(key, item, fields.keys.first, link_options)
|
|
24
|
+
when :time then html << typus_table_datetime_field(key, item, fields.keys.first, link_options)
|
|
25
|
+
when :belongs_to then html << typus_table_belongs_to_field(key, item)
|
|
26
|
+
when :tree then html << typus_table_tree_field(key, item)
|
|
27
|
+
when :position then html << typus_table_position_field(key, item)
|
|
28
|
+
when :has_and_belongs_to_many then
|
|
29
|
+
html << typus_table_has_and_belongs_to_many_field(key, item)
|
|
30
|
+
else
|
|
31
|
+
html << typus_table_string_field(key, item, fields.keys.first, link_options)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# This controls the action to perform. If we are on a model list we
|
|
37
|
+
# will remove the entry, but if we inside a model we will remove the
|
|
38
|
+
# relationship between the models.
|
|
39
|
+
#
|
|
40
|
+
# Only shown is the user can destroy items.
|
|
41
|
+
#
|
|
42
|
+
|
|
43
|
+
if @current_user.can_perform?(model, 'delete')
|
|
44
|
+
|
|
45
|
+
case params[:action]
|
|
46
|
+
when 'index'
|
|
47
|
+
perform = link_to image_tag('admin/trash.gif'), { :action => 'destroy',
|
|
48
|
+
:id => item.id },
|
|
49
|
+
:confirm => _("Remove entry?"),
|
|
50
|
+
:method => :delete
|
|
51
|
+
else
|
|
52
|
+
perform = link_to image_tag('admin/trash.gif'), { :action => 'unrelate',
|
|
53
|
+
:id => params[:id],
|
|
54
|
+
:association => association,
|
|
55
|
+
:resource => model,
|
|
56
|
+
:resource_id => item.id },
|
|
57
|
+
:confirm => _("Unrelate {{unrelate_model}} from {{unrelate_model_from}}?",
|
|
58
|
+
:unrelate_model => model.typus_human_name,
|
|
59
|
+
:unrelate_model_from => @resource[:class].typus_human_name)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
html << <<-HTML
|
|
63
|
+
<td width="10px">#{perform}</td>
|
|
64
|
+
HTML
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
html << <<-HTML
|
|
69
|
+
</tr>
|
|
70
|
+
HTML
|
|
71
|
+
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
html << "</table>"
|
|
75
|
+
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Header of the table
|
|
82
|
+
#
|
|
83
|
+
def typus_table_header(model, fields)
|
|
84
|
+
returning(String.new) do |html|
|
|
85
|
+
headers = []
|
|
86
|
+
fields.each do |key, value|
|
|
87
|
+
|
|
88
|
+
content = model.human_attribute_name(key)
|
|
89
|
+
content += " (#{key})" if key.include?('_id')
|
|
90
|
+
|
|
91
|
+
if (model.model_fields.map(&:first).collect { |i| i.to_s }.include?(key) || model.reflect_on_all_associations(:belongs_to).map(&:name).include?(key.to_sym)) && params[:action] == 'index'
|
|
92
|
+
sort_order = case params[:sort_order]
|
|
93
|
+
when 'asc' then 'desc'
|
|
94
|
+
when 'desc' then 'asc'
|
|
95
|
+
end
|
|
96
|
+
order_by = model.reflect_on_association(key.to_sym).primary_key_name rescue key
|
|
97
|
+
switch = (params[:order_by] == key) ? sort_order : ''
|
|
98
|
+
options = { :order_by => order_by, :sort_order => sort_order }
|
|
99
|
+
content = (link_to "<div class=\"#{switch}\">#{content}</div>", params.merge(options))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
headers << "<th>#{content}</th>"
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
headers << "<th> </th>" if @current_user.can_perform?(model, 'delete')
|
|
106
|
+
html << <<-HTML
|
|
107
|
+
<tr>
|
|
108
|
+
#{headers.join("\n")}
|
|
109
|
+
</tr>
|
|
110
|
+
HTML
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def typus_table_belongs_to_field(attribute, item)
|
|
115
|
+
|
|
116
|
+
action = item.send(attribute).class.typus_options_for(:default_action_on_item) rescue 'edit'
|
|
117
|
+
|
|
118
|
+
content = if !item.send(attribute).kind_of?(NilClass)
|
|
119
|
+
link_to item.send(attribute).typus_name, :controller => "admin/#{attribute.pluralize}", :action => action, :id => item.send(attribute).id
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
<<-HTML
|
|
123
|
+
<td>#{content}</td>
|
|
124
|
+
HTML
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def typus_table_has_and_belongs_to_many_field(attribute, item)
|
|
129
|
+
<<-HTML
|
|
130
|
+
<td>#{item.send(attribute).map { |i| i.typus_name }.join('<br />')}</td>
|
|
131
|
+
HTML
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
# When detection of the attributes is made a default attribute
|
|
136
|
+
# type is set. From the string_field we display other content
|
|
137
|
+
# types.
|
|
138
|
+
#
|
|
139
|
+
def typus_table_string_field(attribute, item, first_field, link_options = {})
|
|
140
|
+
|
|
141
|
+
action = item.class.typus_options_for(:default_action_on_item)
|
|
142
|
+
|
|
143
|
+
content = if first_field == attribute
|
|
144
|
+
link_to item.send(attribute) || item.class.typus_options_for(:nil), link_options.merge(:controller => "admin/#{item.class.name.tableize}", :action => action, :id => item.id)
|
|
145
|
+
else
|
|
146
|
+
item.send(attribute)
|
|
147
|
+
end
|
|
148
|
+
<<-HTML
|
|
149
|
+
<td>#{content}</td>
|
|
150
|
+
HTML
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def typus_table_tree_field(attribute, item)
|
|
154
|
+
<<-HTML
|
|
155
|
+
<td>#{item.parent.typus_name if item.parent}</td>
|
|
156
|
+
HTML
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def typus_table_position_field(attribute, item)
|
|
160
|
+
|
|
161
|
+
html_position = []
|
|
162
|
+
|
|
163
|
+
[['Up', 'move_higher'], ['Down', 'move_lower']].each do |position|
|
|
164
|
+
|
|
165
|
+
options = { :controller => item.class.name.tableize,
|
|
166
|
+
:action => 'position',
|
|
167
|
+
:id => item.id,
|
|
168
|
+
:go => position.last }
|
|
169
|
+
|
|
170
|
+
html_position << <<-HTML
|
|
171
|
+
#{link_to _(position.first), params.merge(options)}
|
|
172
|
+
HTML
|
|
173
|
+
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
<<-HTML
|
|
177
|
+
<td>#{html_position.join('/ ')}</td>
|
|
178
|
+
HTML
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def typus_table_datetime_field(attribute, item, first_field = nil, link_options = {} )
|
|
183
|
+
|
|
184
|
+
action = item.class.typus_options_for(:default_action_on_item)
|
|
185
|
+
|
|
186
|
+
date_format = item.class.typus_date_format(attribute)
|
|
187
|
+
value = !item.send(attribute).nil? ? item.send(attribute).to_s(date_format) : item.class.typus_options_for(:nil)
|
|
188
|
+
content = if first_field == attribute
|
|
189
|
+
link_to value, link_options.merge(:controller => "admin/#{item.class.name.tableize}", :action => action, :id => item.id )
|
|
190
|
+
else
|
|
191
|
+
value
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
<<-HTML
|
|
195
|
+
<td>#{content}</td>
|
|
196
|
+
HTML
|
|
197
|
+
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def typus_table_boolean_field(attribute, item)
|
|
201
|
+
|
|
202
|
+
boolean_icon = item.class.typus_options_for(:icon_on_boolean)
|
|
203
|
+
boolean_hash = item.class.typus_boolean(attribute)
|
|
204
|
+
|
|
205
|
+
status = item.send(attribute)
|
|
206
|
+
|
|
207
|
+
link_text = unless item.send(attribute).nil?
|
|
208
|
+
(boolean_icon) ? image_tag("admin/status_#{status}.gif") : boolean_hash["#{status}".to_sym]
|
|
209
|
+
else
|
|
210
|
+
item.class.typus_options_for(:nil) # Content is nil, so we show nil.
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
options = { :controller => item.class.name.tableize, :action => 'toggle', :field => attribute.gsub(/\?$/,''), :id => item.id }
|
|
214
|
+
|
|
215
|
+
content = if item.class.typus_options_for(:toggle) && !item.send(attribute).nil?
|
|
216
|
+
link_to link_text, params.merge(options), :confirm => _("Change {{attribute}}?", :attribute => item.class.human_attribute_name(attribute).downcase)
|
|
217
|
+
else
|
|
218
|
+
link_text
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
<<-HTML
|
|
222
|
+
<td align="center">#{content}</td>
|
|
223
|
+
HTML
|
|
224
|
+
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
end
|