typus 0.9.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|