mirror of
https://github.com/TracksApp/tracks.git
synced 2025-09-22 05:50:47 +02:00

Up to r881 * 'master' of /Users/jackie/Sites/tracks_svn: (22 commits) Added .gitconfig Added yaml_db plugin: http://opensource.heroku.com/ applied patch from Eric from #732 fixes #730 restores ability to delete user from user management page fixes #724 where editing todos truncates the project name of the todo when the project name contains quotes (") Applied patch from Eric Pallen whcih automatically converts url's to links. Thanks Eric! explain that yaml cannot yet be used for backup as importing is not implemented yet. from mailinglist. hopefully fixes #727.Changes the check on running animation to finished animation regenerate compressed js and cleanup whitespace turns out that getElementsByClassName is removed from prototype and it therfore falls back to the function of the browser which has different semantics. Found here http://www.prototypejs.org/api/utility/getElementsByClassName forgot to create a new compressed js from the previous js changes in the stats page you can downdrill to see the active todos in a certain week from the running time charts. This patch adds the option to see all active todos from the selected week and older. fix #727. Adds a check to prevent expand/collapse while a previous expand/collaps is still animating fixed small problem where updating a todo from mobile resulted in an error becase source_view was nil fixes #726. Thanks Eric Pallen for the fix. The mobile view showed active todos from completed projects while the home page does not. merges changes from tracks1.6 to trunk prepares trunk for 1.6 release fixes #713. Adds behavior for edit/star/delete/check buttons of todo even if there is no todo to show. This makes sure that the behaviors are present when you add a new todo through AJAX. fixes #718. The link included the number of actions which resulted from last commit removed some more whitespace to reduce the download of the mobile view. ...
284 lines
10 KiB
Ruby
284 lines
10 KiB
Ruby
module TodosHelper
|
|
|
|
# #require 'users_controller' Counts the number of incomplete items in the
|
|
# specified context
|
|
#
|
|
def count_items(context)
|
|
count = Todo.find_all("done=0 AND context_id=#{context.id}").length
|
|
end
|
|
|
|
def form_remote_tag_edit_todo( &block )
|
|
form_tag(
|
|
todo_path(@todo), {
|
|
:method => :put,
|
|
:id => dom_id(@todo, 'form'),
|
|
:class => dom_id(@todo, 'form') + " inline-form edit_todo_form" },
|
|
&block )
|
|
apply_behavior 'form.edit_todo_form', make_remote_form(
|
|
:method => :put,
|
|
:before => "this.down('button.positive').startWaiting()",
|
|
:loaded => "this.down('button.positive').stopWaiting()",
|
|
:condition => "!(this.down('button.positive').isWaiting())"),
|
|
:prevent_default => true
|
|
end
|
|
|
|
def set_behavior_for_delete_icon
|
|
parameters = "_source_view=#{@source_view}"
|
|
parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
|
apply_behavior '.item-container a.delete_icon:click', :prevent_default => true do |page|
|
|
page.confirming "'Are you sure that you want to ' + this.title + '?'" do
|
|
page << "itemContainer = this.up('.item-container'); itemContainer.startWaiting();"
|
|
page << remote_to_href(:method => 'delete', :with => "'#{parameters}'", :complete => "itemContainer.stopWaiting();")
|
|
end
|
|
end
|
|
end
|
|
|
|
def remote_delete_icon
|
|
str = link_to( image_tag_for_delete,
|
|
todo_path(@todo), :id => "delete_icon_"+@todo.id.to_s,
|
|
:class => "icon delete_icon", :title => "delete the action '#{@todo.description}'")
|
|
set_behavior_for_delete_icon
|
|
str
|
|
end
|
|
|
|
def set_behavior_for_star_icon
|
|
apply_behavior '.item-container a.star_item:click',
|
|
remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"),
|
|
:prevent_default => true
|
|
end
|
|
|
|
def remote_star_icon
|
|
str = link_to( image_tag_for_star(@todo),
|
|
toggle_star_todo_path(@todo),
|
|
:class => "icon star_item", :title => "star the action '#{@todo.description}'")
|
|
set_behavior_for_star_icon
|
|
str
|
|
end
|
|
|
|
def set_behavior_for_edit_icon
|
|
parameters = "_source_view=#{@source_view}"
|
|
parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
|
apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page|
|
|
page << "Effect.Pulsate(this);"
|
|
page << remote_to_href(:method => 'get', :with => "'#{parameters}'")
|
|
end
|
|
end
|
|
|
|
def remote_edit_icon
|
|
if !@todo.completed?
|
|
str = link_to( image_tag_for_edit,
|
|
edit_todo_path(@todo),
|
|
:class => "icon edit_icon")
|
|
set_behavior_for_edit_icon
|
|
else
|
|
str = '<a class="icon">' + image_tag("blank.png") + "</a> "
|
|
end
|
|
str
|
|
end
|
|
|
|
def set_behavior_for_toggle_checkbox
|
|
parameters = "_source_view=#{@source_view}"
|
|
parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
|
apply_behavior '.item-container input.item-checkbox:click',
|
|
remote_function(:url => javascript_variable('this.value'), :method => 'put',
|
|
:with => "'#{parameters}'")
|
|
end
|
|
|
|
def remote_toggle_checkbox
|
|
str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox')
|
|
set_behavior_for_toggle_checkbox
|
|
str
|
|
end
|
|
|
|
def date_span
|
|
if @todo.completed?
|
|
"<span class=\"grey\">#{format_date( @todo.completed_at )}</span>"
|
|
elsif @todo.deferred?
|
|
show_date( @todo.show_from )
|
|
else
|
|
due_date( @todo.due )
|
|
end
|
|
end
|
|
|
|
def tag_list_text
|
|
@todo.tags.collect{|t| t.name}.join(', ')
|
|
end
|
|
|
|
def tag_list
|
|
tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
|
tag_list = tags_except_starred.collect{|t| "<span class=\"tag #{t.name.gsub(' ','-')}\">" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + "</span>"}.join('')
|
|
"<span class='tags'>#{tag_list}</span>"
|
|
end
|
|
|
|
def tag_list_mobile
|
|
tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
|
# removed the link. TODO: add link to mobile view of tagged actions
|
|
tag_list = tags_except_starred.collect{|t|
|
|
"<span class=\"tag #{t.name.gsub(' ','-')}\">" +
|
|
link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) +
|
|
# link_to(t.name, formatted_tag_path(t, :m)) +
|
|
"</span>"}.join('')
|
|
"<span class='tags'>#{tag_list}</span>"
|
|
end
|
|
|
|
def deferred_due_date
|
|
if @todo.deferred? && @todo.due
|
|
"(action due on #{format_date(@todo.due)})"
|
|
end
|
|
end
|
|
|
|
def project_and_context_links(parent_container_type, opts = {})
|
|
str = ''
|
|
if @todo.completed?
|
|
str += @todo.context.name unless opts[:suppress_context]
|
|
should_suppress_project = opts[:suppress_project] || @todo.project.nil?
|
|
str += ", " unless str.blank? || should_suppress_project
|
|
str += @todo.project.name unless should_suppress_project
|
|
str = "(#{str})" unless str.blank?
|
|
else
|
|
if (['project', 'tag', 'stats', 'search'].include?(parent_container_type))
|
|
str << item_link_to_context( @todo )
|
|
end
|
|
if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id
|
|
str << item_link_to_project( @todo )
|
|
end
|
|
end
|
|
return str
|
|
end
|
|
|
|
# Uses the 'staleness_starts' value from settings.yml (in days) to colour the
|
|
# background of the action appropriately according to the age of the creation
|
|
# date:
|
|
# * l1: created more than 1 x staleness_starts, but < 2 x staleness_starts
|
|
# * l2: created more than 2 x staleness_starts, but < 3 x staleness_starts
|
|
# * l3: created more than 3 x staleness_starts
|
|
#
|
|
def staleness_class(item)
|
|
if item.due || item.completed?
|
|
return ""
|
|
elsif item.created_at < user_time - (prefs.staleness_starts * 3).days
|
|
return " stale_l3"
|
|
elsif item.created_at < user_time - (prefs.staleness_starts * 2).days
|
|
return " stale_l2"
|
|
elsif item.created_at < user_time - (prefs.staleness_starts).days
|
|
return " stale_l1"
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
# Check show_from date in comparison to today's date Flag up date
|
|
# appropriately with a 'traffic light' colour code
|
|
#
|
|
def show_date(d)
|
|
if d == nil
|
|
return ""
|
|
end
|
|
|
|
days = days_from_today(d)
|
|
|
|
case days
|
|
# overdue or due very soon! sound the alarm!
|
|
when -1000..-1
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"red\">Scheduled to show " + (days * -1).to_s + " days ago</span></a> "
|
|
when 0
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"amber\">Show Today</span></a> "
|
|
when 1
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"amber\">Show Tomorrow</span></a> "
|
|
# due 2-7 days away
|
|
when 2..7
|
|
if prefs.due_style == Preference.due_styles[:due_on]
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"orange\">Show on " + d.strftime("%A") + "</span></a> "
|
|
else
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"orange\">Show in " + days.to_s + " days</span></a> "
|
|
end
|
|
# more than a week away - relax
|
|
else
|
|
"<a title=\"" + format_date(d) + "\"><span class=\"green\">Show in " + days.to_s + " days</span></a> "
|
|
end
|
|
end
|
|
|
|
def calendar_setup( input_field )
|
|
str = "Calendar.setup({ ifFormat:\"#{prefs.date_format}\""
|
|
str << ",firstDay:#{prefs.week_starts},showOthers:true,range:[2004, 2010]"
|
|
str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })\n"
|
|
javascript_tag str
|
|
end
|
|
|
|
def item_container_id
|
|
if source_view_is :project
|
|
return "p#{@todo.project_id}" if @todo.active?
|
|
return "tickler" if @todo.deferred?
|
|
end
|
|
return "c#{@todo.context_id}"
|
|
end
|
|
|
|
def should_show_new_item
|
|
|
|
if @todo.project.nil? == false
|
|
# do not show new actions that were added to hidden or completed projects
|
|
# on home page and context page
|
|
return false if source_view_is(:todo) && (@todo.project.hidden? || @todo.project.completed?)
|
|
return false if source_view_is(:context) && (@todo.project.hidden? || @todo.project.completed?)
|
|
end
|
|
|
|
return true if source_view_is(:deferred) && @todo.deferred?
|
|
return true if source_view_is(:project) && @todo.project.hidden? && @todo.project_hidden?
|
|
return true if source_view_is(:project) && @todo.deferred?
|
|
return true if !source_view_is(:deferred) && @todo.active?
|
|
return false
|
|
end
|
|
|
|
def parent_container_type
|
|
return 'tickler' if source_view_is :deferred
|
|
return 'project' if source_view_is :project
|
|
return 'stats' if source_view_is :stats
|
|
return 'context'
|
|
end
|
|
|
|
def empty_container_msg_div_id
|
|
return "tickler-empty-nd" if source_view_is(:project) && @todo.deferred?
|
|
return "p#{@todo.project_id}empty-nd" if source_view_is :project
|
|
return "c#{@todo.context_id}empty-nd"
|
|
end
|
|
|
|
def project_names_for_autocomplete
|
|
array_or_string_for_javascript( ['None'] + @projects.select{ |p| p.active? }.collect{|p| escape_javascript(p.name) } )
|
|
end
|
|
|
|
def context_names_for_autocomplete
|
|
# #return array_or_string_for_javascript(['Create a new context']) if
|
|
# @contexts.empty?
|
|
array_or_string_for_javascript( @contexts.collect{|c| escape_javascript(c.name) } )
|
|
end
|
|
|
|
def format_ical_notes(notes)
|
|
split_notes = notes.split(/\n/)
|
|
joined_notes = split_notes.join("\\n")
|
|
end
|
|
|
|
def formatted_pagination(total)
|
|
s = will_paginate(@todos)
|
|
(s.gsub /(<\/[^<]+>)/, '\1 ').chomp(' ')
|
|
end
|
|
|
|
def date_field_tag(name, id, value = nil, options = {})
|
|
text_field_tag name, value, {"size" => 12, "id" => id, "class" => "Date", "onfocus" => "Calendar.setup", "autocomplete" => "off"}.update(options.stringify_keys)
|
|
end
|
|
|
|
private
|
|
|
|
def image_tag_for_delete
|
|
image_tag("blank.png", :title =>"Delete action", :class=>"delete_item")
|
|
end
|
|
|
|
def image_tag_for_edit
|
|
image_tag("blank.png", :title =>"Edit action", :class=>"edit_item", :id=> dom_id(@todo, 'edit_icon'))
|
|
end
|
|
|
|
def image_tag_for_star(todo)
|
|
class_str = todo.starred? ? "starred_todo" : "unstarred_todo"
|
|
image_tag("blank.png", :title =>"Star action", :class => class_str)
|
|
end
|
|
|
|
end
|