module Admin::TableHelper
def build_typus_table(model, fields, items, link_options = {}, association = nil)
returning(String.new) do |html|
html << <<-HTML
HTML
html << typus_table_header(model, fields)
items.each do |item|
html << <<-HTML
HTML
fields.each do |key, value|
case value
when :boolean then html << typus_table_boolean_field(key, item)
when :datetime then html << typus_table_datetime_field(key, item, link_options)
when :date then html << typus_table_datetime_field(key, item, link_options)
when :file then html << typus_table_file_field(key, item, link_options)
when :time then html << typus_table_datetime_field(key, item, link_options)
when :belongs_to then html << typus_table_belongs_to_field(key, item)
when :tree then html << typus_table_tree_field(key, item)
when :position then html << typus_table_position_field(key, item)
when :has_and_belongs_to_many then
html << typus_table_has_and_belongs_to_many_field(key, item)
else
html << typus_table_string_field(key, item, link_options)
end
end
action = if item.typus_user_id? && !@current_user.is_root?
# If there's a typus_user_id column on the table and logged user is not root ...
item.owned_by?(@current_user) ? 'edit' : 'show'
elsif !@current_user.can_perform?(model, 'edit')
'show'
else
item.class.typus_options_for(:default_action_on_item)
end
content = link_to _(action.capitalize), :controller => "admin/#{item.class.name.tableize}", :action => action, :id => item.id
html << <<-HTML
#{content} |
HTML
##
# This controls the action to perform. If we are on a model list we
# will remove the entry, but if we inside a model we will remove the
# relationship between the models.
#
# Only shown is the user can destroy items.
#
if @current_user.can_perform?(model, 'delete')
trash = "Trash
"
case params[:action]
when 'index'
perform = link_to trash, { :action => 'destroy',
:id => item.id },
:confirm => _("Remove entry?"),
:method => :delete
else
perform = link_to trash, { :action => 'unrelate',
:id => params[:id],
:association => association,
:resource => model,
:resource_id => item.id },
:confirm => _("Unrelate {{unrelate_model}} from {{unrelate_model_from}}?",
:unrelate_model => model.typus_human_name,
:unrelate_model_from => @resource[:class].typus_human_name)
end
html << <<-HTML
#{perform} |
HTML
end
html << <<-HTML
HTML
end
html << "
"
end
end
##
# Header of the table
#
def typus_table_header(model, fields)
returning(String.new) do |html|
headers = []
fields.each do |key, value|
content = model.human_attribute_name(key)
content += " (#{key})" if key.include?('_id')
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'
sort_order = case params[:sort_order]
when 'asc' then ['desc', '↓']
when 'desc' then ['asc', '↑']
else
[nil, nil]
end
order_by = model.reflect_on_association(key.to_sym).primary_key_name rescue key
switch = (params[:order_by] == key) ? sort_order.last : ''
options = { :order_by => order_by, :sort_order => sort_order.first }
content = (link_to "#{content} #{switch}", params.merge(options))
end
headers << "#{content} | "
end
headers << " | " if @current_user.can_perform?(model, 'delete')
html << <<-HTML
#{headers.join("\n")}
HTML
end
end
def typus_table_belongs_to_field(attribute, item)
action = item.send(attribute).class.typus_options_for(:default_action_on_item) rescue 'edit'
content = if !item.send(attribute).kind_of?(NilClass)
link_to item.send(attribute).typus_name, :controller => "admin/#{attribute.pluralize}", :action => action, :id => item.send(attribute).id
end
<<-HTML
#{content} |
HTML
end
def typus_table_has_and_belongs_to_many_field(attribute, item)
<<-HTML
#{item.send(attribute).map { |i| i.typus_name }.join(' ')} |
HTML
end
def typus_table_string_field(attribute, item, link_options = {})
<<-HTML
#{item.send(attribute)} |
HTML
end
def typus_table_file_field(attribute, item, link_options = {})
attachment = attribute.split('_file_name').first
if item.send(attachment).styles.member?(:typus_preview) && item.send("#{attachment}_content_type") =~ /^image\/.+/
<<-HTML
#{item.send(attribute)} |
'zoom')}\">#{item.typus_preview(attachment)}
HTML
else
<<-HTML
#{link_to item.send(attribute), item.send(attachment).url} |
HTML
end
end
def typus_table_tree_field(attribute, item)
<<-HTML
#{item.parent.typus_name if item.parent} |
HTML
end
def typus_table_position_field(attribute, item)
html_position = []
[['Up', 'move_higher'], ['Down', 'move_lower']].each do |position|
options = { :controller => item.class.name.tableize,
:action => 'position',
:id => item.id,
:go => position.last }
first_or_last = (item.respond_to?(:first?) && (position.last == 'move_higher' && item.first?)) || (item.respond_to?(:last?) && (position.last == 'move_lower' && item.last?))
html_position << link_to_unless(first_or_last, _(position.first), params.merge(options)) do |name|
%(#{name})
end
end
<<-HTML
#{html_position.join(' / ')} |
HTML
end
def typus_table_datetime_field(attribute, item, link_options = {} )
date_format = item.class.typus_date_format(attribute)
content = !item.send(attribute).nil? ? item.send(attribute).to_s(date_format) : item.class.typus_options_for(:nil)
<<-HTML
#{content} |
HTML
end
def typus_table_boolean_field(attribute, item)
boolean_hash = item.class.typus_boolean(attribute)
status = item.send(attribute)
link_text = !item.send(attribute).nil? ? boolean_hash["#{status}".to_sym] : item.class.typus_options_for(:nil)
options = { :controller => item.class.name.tableize, :action => 'toggle', :field => attribute.gsub(/\?$/,''), :id => item.id }
content = if item.class.typus_options_for(:toggle) && !item.send(attribute).nil?
link_to link_text, params.merge(options),
:confirm => _("Change {{attribute}}?",
:attribute => item.class.human_attribute_name(attribute).downcase)
else
link_text
end
<<-HTML
#{content} |
HTML
end
end