app/helpers/application_helper.rb
# encoding: UTF-8
# The methods added to this helper will be available to all templates in the application.
module ApplicationHelper
include ERB::Util
def current_pages
@pages ||= current_user.company.pages.projects.where('notable_id in (?)', current_project_ids)
end
def total_today
return @total_today if @total_today
@total_today = 0
start = tz.local_to_utc(tz.now.at_midnight)
@total_today = current_user.work_logs.where('started_at > ? AND started_at < ?', start, start + 1.day).sum(:duration).to_i
@total_today += @current_sheet.duration / 60 if @current_sheet
@total_today
end
def due_time(from_time, to_time = 0)
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
distance_of_time_in_words from_time, to_time
end
def overdue_time(from_time)
time_ago_in_words(from_time, :include_seconds => false)
end
def due_in_words(task)
res = ''
css = due_in_css(task)
due_date = task.due_date
if due_date
local_due = tz.utc_to_local(due_date)
tz_now = tz.now
if local_due > tz_now
res = due_time(tz_now, local_due)
else
res = overdue_time(local_due)
end
end
if res.length > 0
res = "<span class=\"#{css}\">#{res}</span>"
end
return res.html_safe
end
def due_in_css(task)
css = ''
return css if task.resolved?
due_date= task.due_date
if due_date
local_due = tz.utc_to_local(due_date)
tz_now = tz.now
if local_due > tz_now
if (local_due - tz_now) > 7.days
css = 'due_distant'
elsif (local_due - tz_now) >= 2.days
css = 'due_soon'
elsif (local_due - tz_now) >= 1.days
css = 'due_tomorrow'
else
css = 'due'
end
else
css = 'due_overdue'
end
end
css
end
def forecast_in_words(task)
res = ''
css = 'due'
estimate_date = task.estimate_date
if estimate_date
local_due = tz.utc_to_local(estimate_date)
tz_now = tz.now
if local_due > tz_now
res = due_time(tz_now, local_due)
else
res = overdue_time(local_due)
end
end
if res.length > 0
res = "<span class=\"#{css}\">#{res}</span>"
end
return res.html_safe
end
def wrap_text(txt)
txt.gsub!(/#([0-9]+)/, "<a href=\"/tasks/view/\\1\">#\\1</a>")
txt.gsub!(/([\w\.\-\+]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/i, '<a href="mailto:\\0">\\0</a>')
txt.gsub!(/(http\S+(?:gif|jpg|png))(\?.*)?/i, "<a href=\"\\0\" target=\"blank\">\\0</a>")
txt.gsub!(URI.regexp) { |m|
elems = m.match(URI.regexp).to_a
"<a href=\"#{elems[0]}\" target=\"_blank\">".html_safe + elems[0] + '</a>'.html_safe
}
txt.gsub(WikiRevision::WIKI_LINK) { |m|
match = m.match(WikiRevision::WIKI_LINK)
name = text = match[1]
alias_match = match[1].match(WikiRevision::ALIAS_SEPARATION)
if alias_match
name = alias_match[1]
text = alias_match[2]
end
if name.downcase.include? '://'
url = name
else
url = "/wiki/show/#{URI.encode(name)}"
end
"<a href=\"#{url}\">".html_safe + text + '</a>'.html_safe
}
end
def submit_tag(value = 'Save Changes', options={})
or_option = options.delete(:or)
return super + ("<span class='button_or'>"+'or'+' ' + or_option + '</span>').html_safe if or_option
super
end
def ajax_spinner_for(id, spinner='spinner.gif')
"<img src='/images/#{spinner}' style='display:none; vertical-align:middle;' id='#{id}_spinner'> ".html_safe
end
def avatar_for(user, size=32)
if current_user.option_avatars == 1
return "<img src=\"#{user.avatar_url(size, request.ssl?)}\" class=\"photo\" />".html_safe
end
''
end
###
# Returns a string of css style to color task using the
# selected (in the session) coloring.
###
def color_style(task)
color_property = session[:colors].to_i
if color_property > 0
property = current_user.company.properties.detect { |p| p.id == color_property }
else
property = current_user.company.properties.detect { |p| p.default_color }
end
value = task.property_value(property)
if value
return "border-left: 4px solid #{ value.color }; background: none;"
end
end
###
# Return an html tag to display the icon for given task using
# the selected (in the session) icons to display.
###
def task_icon(task)
icon_property = session[:icons].to_i
property = current_user.company.type_property
if icon_property != 0 and !property
property = current_user.company.properties.detect { |p| p.id == icon_property }
end
pv = task.property_value(property)
src = pv.icon_url if pv
return image_tag(File.join('icons', src), :rel => 'tooltip', :alt => pv, :title => pv) if !src.blank?
end
##
# Return the options html for task icons selection.
##
def task_icon_options(pv)
arr = []
Dir.chdir(File.join(Rails.root.to_s, 'app', 'assets', 'images', 'icons')) do
arr = Dir.glob('*.{png,gif,jpg}')
end
arr.map! { |icon| [icon, icon] }
arr.insert(0, ['none', ''])
options_for_select(arr, pv.icon_url)
end
###
# Returns a submit tag suitable for the given object.
# (Create or Update)"
###
def cit_submit_tag(object)
text = object.new_record? ? t('button.create') : t('button.save')
submit_tag(text, :class => 'btn btn-primary')
end
###
# Returns an element to use a handle for sorting the given
# object.
###
def sortable_handle_tag(object)
class_name = "handle #{ object.class.name.underscore }"
image = image_tag('move.gif', :border => 0, :alt => "#{ t('button.move') }", :class => class_name)
object.new_record? ? '' : image
end
###
# Returns the html class to use for the tab menu.
###
def menu_class(resource)
name = controller.controller_name
return 'active' if name == resource
end
###
# Returns the html to use to display a filter for the given
# method, etc
###
def filter_for(meth, names_and_ids, session_filters, label = nil)
label ||= t(meth, scope: 'activerecord.attributes')
session_filters ||= {}
selected = session_filters[meth] || []
selected = names_and_ids.select { |_, id| selected.include?(id.to_s) }
res = query_menu("filter[#{ meth }]", names_and_ids, label)
res += selected_filter_values("filter[#{ meth }]", selected, label)
return res
end
###
# Returns the project id that should be selected based on the current
# session and filters.
###
def selected_project
if @task and @task.project_id.to_i > 0
selected_project = @task.project_id
else
selected_project = current_user.projects.order('name').first.id
end
return selected_project
end
###
# Returns the html to show pagination links for the given
# array.
###
def pagination_links(objects, count = 100)
will_paginate objects, :per_page => count
end
###
# Returns the title for the given log. If the log has no title,
# creates a sensible one.
# If the log has a target, tries to link to that targets page.
###
def log_title_for(log)
title = log.title
title ||= "#{ log.target.class.name.humanize } - #{ log.target }"
if log.target and log.target.respond_to?(:to_url)
title = link_to(title, log.target.to_url)
end
return title
end
###
# Returns the html to display add/remove links for the given attribute value.
# If the value isn't a multi type, returns nothing.
###
def multi_links(custom_attribute_value)
res = ''
value = custom_attribute_value
attr = value.custom_attribute
if attr.multiple?
same_type = (attr == @last_type)
@last_type = attr
add_style = same_type ? 'display: none' : ''
remove_style = same_type ? '' : 'display: none;'
res += link_to_function(t('shared.action_labels.add_another'), 'addAttribute(this)',
:class => 'add_attribute',
:style => add_style)
res += link_to_function(t('shared.action_labels.remove'), 'removeAttribute(this)',
:class => 'remove_attribute',
:style => remove_style)
end
return res.html_safe
end
# Returns a string to use as the field id for the current
# custom attribute edit field
# A new id will be generated each call to this method, so store
# it if you need to use it in more than one place
def custom_attribute_field_id
@ca_field_id ||= 0
@ca_field_id += 1
return "custom_attribute_#{ @ca_field_id }"
end
# return links to edit current task templates
def template_links
current_templates.collect do |t|
link_to t, :controller => 'task_templates', :action => 'edit', :id => t.task_num
end
end
def escape_twice(attr)
h(String.new(h(attr)))
end
def grouped_client_projects_options(projects)
last_customer = nil
options = []
projects.each do |project|
if project.customer != last_customer
options << [h(project.customer.name), []]
last_customer = project.customer
end
options.last[1] << [project.name, project.id]
end
return options
end
def active_class(selected, item)
selected == item ? 'active' : ''
end
def link_to_function(name, function, html_options = {})
data = {:function => "#{function}; return false;".html_safe}
href = html_options[:href] || '#'
# link_to name, href, html_options.merge(:data => data)
content_tag(:a, name, html_options.merge(:href => href, :data => data))
end
end