Remove trailing whitespace and tabs

This commit is contained in:
Matt Rogers 2014-08-14 21:05:05 -05:00
parent 863d780ad0
commit aa41e20e46
84 changed files with 407 additions and 407 deletions

View file

@ -20,7 +20,7 @@ var TracksPages = {
$('#sidebar').html(html); $('#sidebar').html(html);
}, },
slide_up_and_remove: function(selector) { slide_up_and_remove: function(selector) {
$(selector).slideUp(1000, function() { $(selector).slideUp(1000, function() {
$(selector).remove(); $(selector).remove();
}); });
}, },
@ -194,4 +194,4 @@ var TracksPages = {
/* fade flashes and alerts in automatically */ /* fade flashes and alerts in automatically */
$(".alert").fadeOut(8000); $(".alert").fadeOut(8000);
} }
}; };

View file

@ -20,7 +20,7 @@ img {
#minilinks, .defer-container, .menu_sort, .position, .buttons, .sf-item-menu, #minilinks, .defer-container, .menu_sort, .position, .buttons, .sf-item-menu,
.container_toggle, .grip, .show_notes, .recurring_icon, #project-next-prev, .container_toggle, .grip, .show_notes, .recurring_icon, #project-next-prev,
.project_settings, .add_note_link { .project_settings, .add_note_link {
display:none; display:none;
} }
.tag { .tag {
@ -64,7 +64,7 @@ ul {
li { li {
margin: .1em 0 .1em 2em; margin: .1em 0 .1em 2em;
line-height: 1.4em; line-height: 1.4em;
} }
.item-container { .item-container {

View file

@ -339,7 +339,7 @@ a.show_successors:hover, a.link_to_successors:hover {background-image: image-url
width: 14px; width: 14px;
border: 0px; border: 0px;
background: image-url('collapse_expand.png') no-repeat left top; background: image-url('collapse_expand.png') no-repeat left top;
.context_collapsed & { background-position: left bottom; } .context_collapsed & { background-position: left bottom; }
} }
@ -485,7 +485,7 @@ input.item-checkbox {
a.footer_link { a.footer_link {
color: #cc3334; color: #cc3334;
font-style: normal; font-style: normal;
&:hover { &:hover {
color: #fff; color: #fff;
background-color: #cc3334 !important; background-color: #cc3334 !important;

View file

@ -276,7 +276,7 @@ class ApplicationController < ActionController::Base
def done_todos_for(object) def done_todos_for(object)
object_name = object.class.name.downcase # context or project object_name = object.class.name.downcase # context or project
@source_view = "done" @source_view = "done"
eval("@#{object_name} = object") eval("@#{object_name} = object")
@page_title = t("#{object_name.pluralize}.completed_tasks_title", "#{object_name}_name".to_sym => object.name) @page_title = t("#{object_name.pluralize}.completed_tasks_title", "#{object_name}_name".to_sym => object.name)

View file

@ -30,10 +30,10 @@ class ContextsController < ApplicationController
format.autocomplete &render_autocomplete format.autocomplete &render_autocomplete
end end
end end
def show def show
set_context_from_params set_context_from_params
unless @context.nil? unless @context.nil?
@max_completed = current_user.prefs.show_number_completed @max_completed = current_user.prefs.show_number_completed
@done = @context.todos.completed.limit(@max_completed).reorder("todos.completed_at DESC, todos.created_at DESC").includes(Todo::DEFAULT_INCLUDES) @done = @context.todos.completed.limit(@max_completed).reorder("todos.completed_at DESC, todos.created_at DESC").includes(Todo::DEFAULT_INCLUDES)
@ -42,7 +42,7 @@ class ContextsController < ApplicationController
@deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES) @deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
@pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES) @pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES)
@projects = current_user.projects @projects = current_user.projects
@contexts = current_user.contexts @contexts = current_user.contexts
@ -63,7 +63,7 @@ class ContextsController < ApplicationController
end end
end end
end end
def create def create
if params[:format] == 'application/xml' && params['exception'] if params[:format] == 'application/xml' && params['exception']
render_failure "Expected post format is valid xml like so: <context><name>context name</name></context>.", 400 render_failure "Expected post format is valid xml like so: <context><name>context name</name></context>.", 400
@ -95,7 +95,7 @@ class ContextsController < ApplicationController
@context.attributes = context_params @context.attributes = context_params
@saved = @context.save @saved = @context.save
@state_saved = set_state_for_update(@new_state) @state_saved = set_state_for_update(@new_state)
@saved = @saved && @state_saved @saved = @saved && @state_saved
if @saved if @saved
@ -215,7 +215,7 @@ class ContextsController < ApplicationController
render render
end end
end end
def render_autocomplete def render_autocomplete
lambda do lambda do
render :text => for_autocomplete(current_user.contexts, params[:term]) render :text => for_autocomplete(current_user.contexts, params[:term])

View file

@ -1,33 +1,33 @@
class DataController < ApplicationController class DataController < ApplicationController
require 'csv' require 'csv'
def index def index
@page_title = "TRACKS::Export" @page_title = "TRACKS::Export"
end end
def import def import
end end
def csv_map def csv_map
if params[:file].blank? if params[:file].blank?
flash[:notice] = "File can't be blank" flash[:notice] = "File can't be blank"
redirect_to :back redirect_to :back
else else
@import_to = params[:import_to] @import_to = params[:import_to]
begin begin
#get column headers and format as [['name', column_number]...] #get column headers and format as [['name', column_number]...]
i = -1 i = -1
@headers = import_headers(params[:file].path).collect { |v| [v, i+=1] } @headers = import_headers(params[:file].path).collect { |v| [v, i+=1] }
@headers.unshift ['',i] @headers.unshift ['',i]
rescue Exception => e rescue Exception => e
flash[:error] = "Invalid CVS: could not read headers: #{e}" flash[:error] = "Invalid CVS: could not read headers: #{e}"
redirect_to :back redirect_to :back
return return
end end
#save file for later #save file for later
begin begin
uploaded_file = params[:file] uploaded_file = params[:file]
@ -85,12 +85,12 @@ class DataController < ApplicationController
def export def export
# Show list of formats for export # Show list of formats for export
end end
# Thanks to a tip by Gleb Arshinov # Thanks to a tip by Gleb Arshinov
# <http://lists.rubyonrails.org/pipermail/rails/2004-November/000199.html> # <http://lists.rubyonrails.org/pipermail/rails/2004-November/000199.html>
def yaml_export def yaml_export
all_tables = {} all_tables = {}
all_tables['todos'] = current_user.todos.includes(:tags).load all_tables['todos'] = current_user.todos.includes(:tags).load
all_tables['contexts'] = current_user.contexts.load all_tables['contexts'] = current_user.contexts.load
all_tables['projects'] = current_user.projects.load all_tables['projects'] = current_user.projects.load
@ -114,12 +114,12 @@ class DataController < ApplicationController
all_tables['taggings'] = taggings.load all_tables['taggings'] = taggings.load
all_tables['notes'] = current_user.notes.load all_tables['notes'] = current_user.notes.load
all_tables['recurring_todos'] = current_user.recurring_todos.load all_tables['recurring_todos'] = current_user.recurring_todos.load
result = all_tables.to_yaml result = all_tables.to_yaml
result.gsub!(/\n/, "\r\n") # TODO: general functionality for line endings result.gsub!(/\n/, "\r\n") # TODO: general functionality for line endings
send_data(result, :filename => "tracks_backup.yml", :type => 'text/plain') send_data(result, :filename => "tracks_backup.yml", :type => 'text/plain')
end end
# export all actions as csv # export all actions as csv
def csv_actions def csv_actions
content_type = 'text/csv' content_type = 'text/csv'
@ -163,7 +163,7 @@ class DataController < ApplicationController
end end
send_data(result, :filename => "notes.csv", :type => content_type) send_data(result, :filename => "notes.csv", :type => content_type)
end end
def xml_export def xml_export
todo_tag_ids = Tag.find_by_sql([ todo_tag_ids = Tag.find_by_sql([
"SELECT DISTINCT tags.id "+ "SELECT DISTINCT tags.id "+
@ -191,7 +191,7 @@ class DataController < ApplicationController
result << "</tracks_data>" result << "</tracks_data>"
send_data(result, :filename => "tracks_data.xml", :type => 'text/xml') send_data(result, :filename => "tracks_data.xml", :type => 'text/xml')
end end
def yaml_form def yaml_form
# Draw the form to input the YAML text data # Draw the form to input the YAML text data
end end
@ -206,7 +206,7 @@ class DataController < ApplicationController
end end
def yaml_import def yaml_import
raise "YAML loading is disabled" raise "YAML loading is disabled"
end end
end end

View file

@ -4,27 +4,27 @@ class FeedlistController < ApplicationController
def index def index
@page_title = 'TRACKS::Feeds' @page_title = 'TRACKS::Feeds'
unless mobile? unless mobile?
init_data_for_sidebar init_data_for_sidebar
else else
@projects = current_user.projects @projects = current_user.projects
@contexts = current_user.contexts @contexts = current_user.contexts
end end
@active_projects = current_user.projects.active @active_projects = current_user.projects.active
@hidden_projects = current_user.projects.hidden @hidden_projects = current_user.projects.hidden
@completed_projects = current_user.projects.completed @completed_projects = current_user.projects.completed
@active_contexts = current_user.contexts.active @active_contexts = current_user.contexts.active
@hidden_contexts = current_user.contexts.hidden @hidden_contexts = current_user.contexts.hidden
respond_to do |format| respond_to do |format|
format.html format.html
format.m format.m
end end
end end
def get_feeds_for_context def get_feeds_for_context
get_feeds_for(@context = current_user.contexts.find(params[:context_id])) get_feeds_for(@context = current_user.contexts.find(params[:context_id]))
end end

View file

@ -1,16 +1,16 @@
class IntegrationsController < ApplicationController class IntegrationsController < ApplicationController
require 'mail' require 'mail'
skip_before_filter :login_required, :only => [:cloudmailin, :search_plugin, :google_gadget] skip_before_filter :login_required, :only => [:cloudmailin, :search_plugin, :google_gadget]
def index def index
@page_title = 'TRACKS::Integrations' @page_title = 'TRACKS::Integrations'
end end
def rest_api def rest_api
@page_title = 'TRACKS::REST API Documentation' @page_title = 'TRACKS::REST API Documentation'
end end
def get_quicksilver_applescript def get_quicksilver_applescript
get_applescript('quicksilver_applescript') get_applescript('quicksilver_applescript')
end end
@ -31,20 +31,20 @@ class IntegrationsController < ApplicationController
def google_gadget def google_gadget
render :layout => false, :content_type => Mime::XML render :layout => false, :content_type => Mime::XML
end end
def cloudmailin def cloudmailin
if !verify_cloudmailin_signature if !verify_cloudmailin_signature
render :text => "Message signature verification failed.", :status => 403 render :text => "Message signature verification failed.", :status => 403
return false return false
end end
if process_message(params[:message]) if process_message(params[:message])
render :text => 'success', :status => 200 render :text => 'success', :status => 200
else else
render :text => "No user found or other error", :status => 404 render :text => "No user found or other error", :status => 404
end end
end end
private private
def process_message(message) def process_message(message)
@ -56,10 +56,10 @@ class IntegrationsController < ApplicationController
signature = Digest::MD5.hexdigest(request.request_parameters.sort{|a,b| a[0].to_s <=> b[0].to_s}.map{|k,v| v}.join + SITE_CONFIG['cloudmailin']) signature = Digest::MD5.hexdigest(request.request_parameters.sort{|a,b| a[0].to_s <=> b[0].to_s}.map{|k,v| v}.join + SITE_CONFIG['cloudmailin'])
return provided == signature return provided == signature
end end
def get_applescript(partial_name) def get_applescript(partial_name)
context = current_user.contexts.find params[:context_id] context = current_user.contexts.find params[:context_id]
render :partial => partial_name, :locals => { :context => context } render :partial => partial_name, :locals => { :context => context }
end end
end end

View file

@ -56,7 +56,7 @@ class NotesController < ApplicationController
def destroy def destroy
@note = current_user.notes.find(params['id']) @note = current_user.notes.find(params['id'])
@note.destroy @note.destroy
respond_to do |format| respond_to do |format|
format.html format.html
format.js { @down_count = current_user.notes.size } format.js { @down_count = current_user.notes.size }

View file

@ -35,11 +35,11 @@ private
def prefs_params def prefs_params
params.require(:prefs).permit( params.require(:prefs).permit(
:date_format, :week_starts, :show_number_completed, :date_format, :week_starts, :show_number_completed,
:show_completed_projects_in_sidebar, :show_hidden_contexts_in_sidebar, :show_completed_projects_in_sidebar, :show_hidden_contexts_in_sidebar,
:staleness_starts, :due_style, :locale, :title_date_format, :time_zone, :staleness_starts, :due_style, :locale, :title_date_format, :time_zone,
:show_hidden_projects_in_sidebar, :show_project_on_todo_done, :show_hidden_projects_in_sidebar, :show_project_on_todo_done,
:review_period, :refresh, :verbose_action_descriptors, :review_period, :refresh, :verbose_action_descriptors,
:mobile_todos_per_page, :sms_email, :sms_context_id) :mobile_todos_per_page, :sms_email, :sms_context_id)
end end
@ -52,5 +52,5 @@ private
notify :notice, t('preferences.updated') notify :notice, t('preferences.updated')
redirect_to :action => 'index' redirect_to :action => 'index'
end end
end end

View file

@ -95,7 +95,7 @@ class ProjectsController < ApplicationController
def set_reviewed def set_reviewed
@project.last_reviewed = Time.zone.now @project.last_reviewed = Time.zone.now
@project.save @project.save
case @source_view case @source_view
when "project" when "project"
redirect_to :action => 'show' redirect_to :action => 'show'
@ -219,7 +219,7 @@ class ProjectsController < ApplicationController
update_state_counts update_state_counts
init_data_for_sidebar init_data_for_sidebar
init_project_hidden_todo_counts(['project']) init_project_hidden_todo_counts(['project'])
template = 'projects/update' template = 'projects/update'
# TODO: are these params ever set? or is this dead code? # TODO: are these params ever set? or is this dead code?
@ -318,7 +318,7 @@ class ProjectsController < ApplicationController
@show_hidden_projects = @hidden_projects_count > 0 @show_hidden_projects = @hidden_projects_count > 0
@show_completed_projects = @completed_projects_count > 0 @show_completed_projects = @completed_projects_count > 0
end end
def set_project_from_params def set_project_from_params
@project = current_user.projects.find_by_params(params) @project = current_user.projects.find_by_params(params)
end end

View file

@ -63,8 +63,8 @@ class RecurringTodosController < ApplicationController
@recurring_todo = builder.saved_recurring_todo @recurring_todo = builder.saved_recurring_todo
todo_saved = TodoFromRecurringTodo.new(current_user, @recurring_todo).create.nil? == false todo_saved = TodoFromRecurringTodo.new(current_user, @recurring_todo).create.nil? == false
@status_message = @status_message =
t('todos.recurring_action_saved') + " / " + t('todos.recurring_action_saved') + " / " +
t("todos.new_related_todo_#{todo_saved ? "" : "not_"}created_short") t("todos.new_related_todo_#{todo_saved ? "" : "not_"}created_short")
@down_count = current_user.recurring_todos.active.count @down_count = current_user.recurring_todos.active.count
@ -144,30 +144,30 @@ class RecurringTodosController < ApplicationController
def recurring_todo_params def recurring_todo_params
params.require(:recurring_todo).permit( params.require(:recurring_todo).permit(
# model attributes # model attributes
:context_id, :project_id, :description, :notes, :state, :start_from, :context_id, :project_id, :description, :notes, :state, :start_from,
:ends_on, :end_date, :number_of_occurences, :occurences_count, :target, :ends_on, :end_date, :number_of_occurences, :occurences_count, :target,
:show_from_delta, :recurring_period, :recurrence_selector, :every_other1, :show_from_delta, :recurring_period, :recurrence_selector, :every_other1,
:every_other2, :every_other3, :every_day, :only_work_days, :every_count, :every_other2, :every_other3, :every_day, :only_work_days, :every_count,
:weekday, :show_always, :context_name, :project_name, :tag_list, :weekday, :show_always, :context_name, :project_name, :tag_list,
# form attributes # form attributes
:recurring_period, :daily_selector, :monthly_selector, :yearly_selector, :recurring_period, :daily_selector, :monthly_selector, :yearly_selector,
:recurring_target, :daily_every_x_days, :monthly_day_of_week, :recurring_target, :daily_every_x_days, :monthly_day_of_week,
:monthly_every_x_day, :monthly_every_x_month2, :monthly_every_x_month, :monthly_every_x_day, :monthly_every_x_month2, :monthly_every_x_month,
:monthly_every_xth_day, :recurring_show_days_before, :monthly_every_xth_day, :recurring_show_days_before,
:recurring_show_always, :weekly_every_x_week, :weekly_return_monday, :recurring_show_always, :weekly_every_x_week, :weekly_return_monday,
:yearly_day_of_week, :yearly_every_x_day, :yearly_every_xth_day, :yearly_day_of_week, :yearly_every_x_day, :yearly_every_xth_day,
:yearly_month_of_year2, :yearly_month_of_year, :yearly_month_of_year2, :yearly_month_of_year,
# derived attribues # derived attribues
:weekly_return_monday, :weekly_return_tuesday, :weekly_return_wednesday, :weekly_return_monday, :weekly_return_tuesday, :weekly_return_wednesday,
:weekly_return_thursday, :weekly_return_friday, :weekly_return_saturday, :weekly_return_sunday :weekly_return_thursday, :weekly_return_friday, :weekly_return_saturday, :weekly_return_sunday
) )
end end
def all_recurring_todo_params def all_recurring_todo_params
# move context_name, project_name and tag_list into :recurring_todo hash for easier processing # move context_name, project_name and tag_list into :recurring_todo hash for easier processing
{ {
context_name: :context_name, context_name: :context_name,
project_name: :project_name, project_name: :project_name,
tag_list: :tag_list tag_list: :tag_list
}.each do |target,source| }.each do |target,source|
move_into_recurring_todo_param(params, target, source) move_into_recurring_todo_param(params, target, source)
@ -181,15 +181,15 @@ class RecurringTodosController < ApplicationController
# Same goes for start_from and end_date # Same goes for start_from and end_date
params['recurring_todo']['recurring_period'] = params['recurring_edit_todo']['recurring_period'] params['recurring_todo']['recurring_period'] = params['recurring_edit_todo']['recurring_period']
{ {
context_name: :context_name, context_name: :context_name,
project_name: :project_name, project_name: :project_name,
tag_list: :edit_recurring_todo_tag_list, tag_list: :edit_recurring_todo_tag_list,
end_date: :recurring_todo_edit_end_date, end_date: :recurring_todo_edit_end_date,
start_from: :recurring_todo_edit_start_from start_from: :recurring_todo_edit_start_from
}.each do |target,source| }.each do |target,source|
move_into_recurring_todo_param(params, target, source) move_into_recurring_todo_param(params, target, source)
end end
# make sure that we set weekly_return_xxx to empty (space) when they are # make sure that we set weekly_return_xxx to empty (space) when they are
# not checked (and thus not present in params["recurring_todo"]) # not checked (and thus not present in params["recurring_todo"])

View file

@ -1,7 +1,7 @@
class SearchController < ApplicationController class SearchController < ApplicationController
helper :todos, :application, :notes, :projects, :contexts helper :todos, :application, :notes, :projects, :contexts
def results def results
@source_view = params['_source_view'] || 'search' @source_view = params['_source_view'] || 'search'
@page_title = "TRACKS::Search Results for #{params[:search]}" @page_title = "TRACKS::Search Results for #{params[:search]}"

View file

@ -10,7 +10,7 @@ class StatsController < ApplicationController
@hidden_contexts = current_user.contexts.hidden @hidden_contexts = current_user.contexts.hidden
@stats = Stats::UserStats.new(current_user) @stats = Stats::UserStats.new(current_user)
end end
def actions_done_last12months_data def actions_done_last12months_data
# get actions created and completed in the past 12+3 months. +3 for running # get actions created and completed in the past 12+3 months. +3 for running
# - outermost set of entries needed for these calculations # - outermost set of entries needed for these calculations
@ -19,7 +19,7 @@ class StatsController < ApplicationController
# convert to array and fill in non-existing months # convert to array and fill in non-existing months
@actions_done_last12months_array = put_events_into_month_buckets(actions_last12months, 13, :completed_at) @actions_done_last12months_array = put_events_into_month_buckets(actions_last12months, 13, :completed_at)
@actions_created_last12months_array = put_events_into_month_buckets(actions_last12months, 13, :created_at) @actions_created_last12months_array = put_events_into_month_buckets(actions_last12months, 13, :created_at)
# find max for graph in both arrays # find max for graph in both arrays
@max = (@actions_done_last12months_array + @actions_created_last12months_array).max @max = (@actions_done_last12months_array + @actions_created_last12months_array).max
@ -54,7 +54,7 @@ class StatsController < ApplicationController
def actions_done_lastyears_data def actions_done_lastyears_data
actions_last_months = current_user.todos.select("completed_at,created_at") actions_last_months = current_user.todos.select("completed_at,created_at")
month_count = difference_in_months(@today, actions_last_months.minimum(:created_at)) month_count = difference_in_months(@today, actions_last_months.minimum(:created_at))
# because this action is not scoped by date, the minimum created_at should always be # because this action is not scoped by date, the minimum created_at should always be
# less than the minimum completed_at, so no reason to check minimum completed_at # less than the minimum completed_at, so no reason to check minimum completed_at
@ -101,10 +101,10 @@ class StatsController < ApplicationController
# convert to array and fill in non-existing weeks with 0 # convert to array and fill in non-existing weeks with 0
@max_weeks = @actions_completion_time.last ? difference_in_weeks(@today, @actions_completion_time.last.completed_at) : 1 @max_weeks = @actions_completion_time.last ? difference_in_weeks(@today, @actions_completion_time.last.completed_at) : 1
@actions_completed_per_week_array = convert_to_weeks_running_array(@actions_completion_time, @max_weeks+1) @actions_completed_per_week_array = convert_to_weeks_running_array(@actions_completion_time, @max_weeks+1)
# stop the chart after 10 weeks # stop the chart after 10 weeks
@count = [10, @max_weeks].min @count = [10, @max_weeks].min
# convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off # convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off
@actions_completion_time_array = cut_off_array_with_sum(@actions_completed_per_week_array, @count) @actions_completion_time_array = cut_off_array_with_sum(@actions_completed_per_week_array, @count)
@max_actions = @actions_completion_time_array.max @max_actions = @actions_completion_time_array.max
@ -124,14 +124,14 @@ class StatsController < ApplicationController
# cut off chart at 52 weeks = one year # cut off chart at 52 weeks = one year
@count = [52, @max_weeks].min @count = [52, @max_weeks].min
# convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off # convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off
@actions_running_time_array = cut_off_array_with_sum(@actions_running_per_week_array, @count) @actions_running_time_array = cut_off_array_with_sum(@actions_running_per_week_array, @count)
@max_actions = @actions_running_time_array.max @max_actions = @actions_running_time_array.max
# get percentage done cumulative # get percentage done cumulative
@cum_percent_done = convert_to_cumulative_array(@actions_running_time_array, @actions_running_time.count ) @cum_percent_done = convert_to_cumulative_array(@actions_running_time_array, @actions_running_time.count )
render :layout => false render :layout => false
end end
@ -153,7 +153,7 @@ class StatsController < ApplicationController
# cut off chart at 52 weeks = one year # cut off chart at 52 weeks = one year
@count = [52, @max_weeks].min @count = [52, @max_weeks].min
# convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off # convert to new array to hold max @cut_off elems + 1 for sum of actions after @cut_off
@actions_running_time_array = cut_off_array_with_sum(@actions_running_per_week_array, @count) @actions_running_time_array = cut_off_array_with_sum(@actions_running_per_week_array, @count)
@max_actions = @actions_running_time_array.max @max_actions = @actions_running_time_array.max
@ -163,21 +163,21 @@ class StatsController < ApplicationController
render :layout => false render :layout => false
end end
def actions_open_per_week_data def actions_open_per_week_data
@actions_started = current_user.todos.created_after(@today-53.weeks). @actions_started = current_user.todos.created_after(@today-53.weeks).
select("todos.created_at, todos.completed_at"). select("todos.created_at, todos.completed_at").
reorder("todos.created_at DESC") reorder("todos.created_at DESC")
@max_weeks = difference_in_weeks(@today, @actions_started.last.created_at) @max_weeks = difference_in_weeks(@today, @actions_started.last.created_at)
# cut off chart at 52 weeks = one year # cut off chart at 52 weeks = one year
@count = [52, @max_weeks].min @count = [52, @max_weeks].min
@actions_open_per_week_array = convert_to_weeks_running_from_today_array(@actions_started, @max_weeks+1) @actions_open_per_week_array = convert_to_weeks_running_from_today_array(@actions_started, @max_weeks+1)
@actions_open_per_week_array = cut_off_array(@actions_open_per_week_array, @count) @actions_open_per_week_array = cut_off_array(@actions_open_per_week_array, @count)
@max_actions = (@actions_open_per_week_array.max or 0) @max_actions = (@actions_open_per_week_array.max or 0)
render :layout => false render :layout => false
end end
@ -323,7 +323,7 @@ class StatsController < ApplicationController
selected_todo_ids = get_ids_from(@actions_running_time, week_from, week_to, params['id']=='art_end') selected_todo_ids = get_ids_from(@actions_running_time, week_from, week_to, params['id']=='art_end')
@selected_actions = selected_todo_ids.size == 0 ? [] : current_user.todos.where("id in (#{selected_todo_ids.join(",")})") @selected_actions = selected_todo_ids.size == 0 ? [] : current_user.todos.where("id in (#{selected_todo_ids.join(",")})")
@count = @selected_actions.size @count = @selected_actions.size
render :action => "show_selection_from_chart" render :action => "show_selection_from_chart"
else else
# render error # render error
@ -380,7 +380,7 @@ class StatsController < ApplicationController
records.each { |r| (yield r).each { |i| a[i] += 1 if a[i] } } records.each { |r| (yield r).each { |i| a[i] += 1 if a[i] } }
a a
end end
def put_events_into_month_buckets(records, array_size, date_method_on_todo) def put_events_into_month_buckets(records, array_size, date_method_on_todo)
convert_to_array(records.select { |x| x.send(date_method_on_todo) }, array_size) { |r| [difference_in_months(@today, r.send(date_method_on_todo))]} convert_to_array(records.select { |x| x.send(date_method_on_todo) }, array_size) { |r| [difference_in_months(@today, r.send(date_method_on_todo))]}
end end
@ -400,7 +400,7 @@ class StatsController < ApplicationController
def convert_to_weeks_running_from_today_array(records, array_size) def convert_to_weeks_running_from_today_array(records, array_size)
return convert_to_array(records, array_size) { |r| week_indexes_of(r) } return convert_to_array(records, array_size) { |r| week_indexes_of(r) }
end end
def week_indexes_of(record) def week_indexes_of(record)
a = [] a = []
start_week = difference_in_weeks(@today, record.created_at) start_week = difference_in_weeks(@today, record.created_at)
@ -408,7 +408,7 @@ class StatsController < ApplicationController
end_week.upto(start_week) { |i| a << i }; end_week.upto(start_week) { |i| a << i };
return a return a
end end
# returns a new array containing all elems of array up to cut_off and # returns a new array containing all elems of array up to cut_off and
# adds the sum of the rest of array to the last elem # adds the sum of the rest of array to the last elem
def cut_off_array_with_sum(array, cut_off) def cut_off_array_with_sum(array, cut_off)
@ -418,7 +418,7 @@ class StatsController < ApplicationController
a[cut_off] += array.inject(:+) - a.inject(:+) a[cut_off] += array.inject(:+) - a.inject(:+)
return a return a
end end
def cut_off_array(array, cut_off) def cut_off_array(array, cut_off)
return Array.new(cut_off){|i| array[i]||0} return Array.new(cut_off){|i| array[i]||0}
end end
@ -441,7 +441,7 @@ class StatsController < ApplicationController
def difference_in_days(date1, date2) def difference_in_days(date1, date2)
return ((date1.utc.at_midnight-date2.utc.at_midnight)/SECONDS_PER_DAY).to_i return ((date1.utc.at_midnight-date2.utc.at_midnight)/SECONDS_PER_DAY).to_i
end end
# assumes date1 > date2 # assumes date1 > date2
def difference_in_weeks(date1, date2) def difference_in_weeks(date1, date2)
return difference_in_days(date1, date2) / 7 return difference_in_days(date1, date2) / 7
@ -458,7 +458,7 @@ class StatsController < ApplicationController
# sets "null" on first column and - if necessary - cleans up last two columns, which may have insufficient data # sets "null" on first column and - if necessary - cleans up last two columns, which may have insufficient data
def compute_running_avg_array(set, upper_bound) def compute_running_avg_array(set, upper_bound)
result = set_three_month_avg(set, upper_bound) result = set_three_month_avg(set, upper_bound)
result[upper_bound-1] = result[upper_bound-1] * 3 if upper_bound == set.length result[upper_bound-1] = result[upper_bound-1] * 3 if upper_bound == set.length
result[upper_bound-2] = result[upper_bound-2] * 3 / 2 if upper_bound > 1 and upper_bound == set.length result[upper_bound-2] = result[upper_bound-2] * 3 / 2 if upper_bound > 1 and upper_bound == set.length
result[0] = "null" result[0] = "null"
result result

View file

@ -27,9 +27,9 @@ module Todos
@attributes = todo_params(params) @attributes = todo_params(params)
end end
@attributes = {} if @attributes.nil? # make sure there is at least an empty hash @attributes = {} if @attributes.nil? # make sure there is at least an empty hash
end end
def filter_tags def filter_tags
if @attributes[:tags] if @attributes[:tags]
# for single tags, @attributed[:tags] returns a hash. For multiple tags, # for single tags, @attributed[:tags] returns a hash. For multiple tags,
# it with return an array of hashes. Make sure it is always an array of hashes # it with return an array of hashes. Make sure it is always an array of hashes
@ -38,13 +38,13 @@ module Todos
@attributes[:add_tags] = @attributes[:tags] @attributes[:add_tags] = @attributes[:tags]
@attributes.delete :tags @attributes.delete :tags
end end
end end
def filter_starred def filter_starred
if @params[:new_todo_starred] if @params[:new_todo_starred]
@attributes["starred"] = (@params[:new_todo_starred]||"").include? "true" @attributes["starred"] = (@params[:new_todo_starred]||"").include? "true"
end end
end end
def attributes def attributes
@attributes @attributes
@ -121,10 +121,10 @@ module Todos
private private
def todo_params(params) def todo_params(params)
# keep :predecessor_dependencies from being filterd (for XML API). # keep :predecessor_dependencies from being filterd (for XML API).
# The permit cannot handle multiple precessors # The permit cannot handle multiple precessors
if params[:todo][:predecessor_dependencies] if params[:todo][:predecessor_dependencies]
deps = params[:todo][:predecessor_dependencies][:predecessor] deps = params[:todo][:predecessor_dependencies][:predecessor]
end end
# accept empty :todo hash # accept empty :todo hash
@ -133,8 +133,8 @@ module Todos
end end
filtered = params.require(:todo).permit( filtered = params.require(:todo).permit(
:context_id, :project_id, :description, :notes, :context_id, :project_id, :description, :notes,
:due, :show_from, :state, :due, :show_from, :state,
# XML API # XML API
:tags => [:tag => [:name]], :tags => [:tag => [:name]],
:context => [:name], :context => [:name],

View file

@ -49,7 +49,7 @@ class TodosController < ApplicationController
end end
format.xml do format.xml do
@xml_todos = params[:limit_to_active_todos] ? @not_done_todos : @todos @xml_todos = params[:limit_to_active_todos] ? @not_done_todos : @todos
render :xml => @xml_todos.to_xml( *todo_xml_params ) render :xml => @xml_todos.to_xml( *todo_xml_params )
end end
format.any(:rss, :atom) { @feed_title, @feed_description = 'Tracks Actions', "Actions for #{current_user.display_name}" } format.any(:rss, :atom) { @feed_title, @feed_description = 'Tracks Actions', "Actions for #{current_user.display_name}" }
format.ics format.ics
@ -110,7 +110,7 @@ class TodosController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
redirect_to :action => "index" redirect_to :action => "index"
end end
format.m do format.m do
@return_path=cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path @return_path=cookies[:mobile_url] ? cookies[:mobile_url] : mobile_path
@ -598,7 +598,7 @@ class TodosController < ApplicationController
get_params_for_tag_view get_params_for_tag_view
@page_title = t('todos.tagged_page_title', :tag_name => @tag_title) @page_title = t('todos.tagged_page_title', :tag_name => @tag_title)
@source_view = params['_source_view'] || 'tag' @source_view = params['_source_view'] || 'tag'
init_data_for_sidebar unless mobile? init_data_for_sidebar unless mobile?
todos_with_tag_ids = find_todos_with_tag_expr(@tag_expr) todos_with_tag_ids = find_todos_with_tag_expr(@tag_expr)
@ -751,7 +751,7 @@ class TodosController < ApplicationController
items. items.
includes(:context, :project). includes(:context, :project).
reorder('description ASC'). reorder('description ASC').
limit(10) limit(10)
end end
def auto_complete_for_predecessor def auto_complete_for_predecessor
@ -1195,7 +1195,7 @@ end
def update_date_for_update(key) def update_date_for_update(key)
params['todo'][key] = params["todo"].has_key?(key) ? parse_date_for_update(params["todo"][key], t("todos.error.invalid_#{key}_date")) : "" params['todo'][key] = params["todo"].has_key?(key) ? parse_date_for_update(params["todo"][key], t("todos.error.invalid_#{key}_date")) : ""
end end
def update_due_and_show_from_dates def update_due_and_show_from_dates
%w{ due show_from }.each {|date| update_date_for_update(date) } %w{ due show_from }.each {|date| update_date_for_update(date) }
@ -1233,7 +1233,7 @@ end
def update_attributes_of_todo def update_attributes_of_todo
# TODO: duplication with todo_create_params_helper # TODO: duplication with todo_create_params_helper
@todo.attributes = params.require(:todo).permit( @todo.attributes = params.require(:todo).permit(
:context_id, :project_id, :description, :notes, :context_id, :project_id, :description, :notes,
:due, :show_from, :state) :due, :show_from, :state)
end end
@ -1329,6 +1329,6 @@ end
else else
redirect_to(uri.path) redirect_to(uri.path)
end end
end end
end end

View file

@ -1,5 +1,5 @@
class UsersController < ApplicationController class UsersController < ApplicationController
before_filter :admin_login_required, :only => [ :index, :show, :destroy ] before_filter :admin_login_required, :only => [ :index, :show, :destroy ]
skip_before_filter :login_required, :only => [ :new, :create ] skip_before_filter :login_required, :only => [ :new, :create ]
skip_before_filter :check_for_deprecated_password_hash, skip_before_filter :check_for_deprecated_password_hash,

View file

@ -8,9 +8,9 @@ module ApplicationHelper
menu_name = @group_view_by == 'context' ? 'project' : 'context' menu_name = @group_view_by == 'context' ? 'project' : 'context'
content_tag(:li) do content_tag(:li) do
link_to( link_to(
t("layouts.navigation.group_view_by_#{menu_name}"), t("layouts.navigation.group_view_by_#{menu_name}"),
'#', '#',
{:id => "group_view_by_link", :accesskey => "g", :title => t('layouts.navigation.group_view_by_title'), :x_current_group_by => @group_view_by} ) {:id => "group_view_by_link", :accesskey => "g", :title => t('layouts.navigation.group_view_by_title'), :x_current_group_by => @group_view_by} )
end end
end end
@ -18,14 +18,14 @@ module ApplicationHelper
def container_toggle(id) def container_toggle(id)
link_to( link_to(
image_tag("blank.png", :alt => t('common.collapse_expand')), image_tag("blank.png", :alt => t('common.collapse_expand')),
"#", "#",
{:class => "container_toggle", :id => id} ) {:class => "container_toggle", :id => id} )
end end
def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference) def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference)
link_to name, options, html_options link_to name, options, html_options
end end
# Check due date in comparison to today's date Flag up date appropriately with # Check due date in comparison to today's date Flag up date appropriately with
# a 'traffic light' colour code # a 'traffic light' colour code
# #
@ -39,7 +39,7 @@ module ApplicationHelper
def due_date_mobile(due) def due_date_mobile(due)
return DateLabelHelper::DueDateView.new(due, prefs).due_date_mobile_html return DateLabelHelper::DueDateView.new(due, prefs).due_date_mobile_html
end end
# Returns a count of next actions in the given context or project. The result # Returns a count of next actions in the given context or project. The result
# is count and a string descriptor, correctly pluralised if there are no # is count and a string descriptor, correctly pluralised if there are no
# actions or multiple actions # actions or multiple actions
@ -57,11 +57,11 @@ module ApplicationHelper
s += ", #{t('common.note', :count => project.note_count)}" unless project.note_count == 0 s += ", #{t('common.note', :count => project.note_count)}" unless project.note_count == 0
s.html_safe s.html_safe
end end
def link_to_context(context, descriptor = sanitize(context.name)) def link_to_context(context, descriptor = sanitize(context.name))
link_to( descriptor, context, :title => "View context: #{context.name}" ) link_to( descriptor, context, :title => "View context: #{context.name}" )
end end
def link_to_project(project, descriptor = sanitize(project.name)) def link_to_project(project, descriptor = sanitize(project.name))
link_to( descriptor, project, :title => "View project: #{project.name}" ) link_to( descriptor, project, :title => "View project: #{project.name}" )
end end
@ -70,19 +70,19 @@ module ApplicationHelper
link_to(descriptor, edit_note_path(note), link_to(descriptor, edit_note_path(note),
{:id => "link_edit_#{dom_id(note)}", :class => "note_edit_settings"}) {:id => "link_edit_#{dom_id(note)}", :class => "note_edit_settings"})
end end
def link_to_project_mobile(project, accesskey, descriptor = sanitize(project.name)) def link_to_project_mobile(project, accesskey, descriptor = sanitize(project.name))
link_to( descriptor, project_path(project, :format => 'm'), {:title => "View project: #{project.name}", :accesskey => accesskey} ) link_to( descriptor, project_path(project, :format => 'm'), {:title => "View project: #{project.name}", :accesskey => accesskey} )
end end
def item_link_to_context(item) def item_link_to_context(item)
link_to_context( item.context, prefs.verbose_action_descriptors ? "[#{item.context.name}]" : "[C]" ) link_to_context( item.context, prefs.verbose_action_descriptors ? "[#{item.context.name}]" : "[C]" )
end end
def item_link_to_project(item) def item_link_to_project(item)
link_to_project( item.project, prefs.verbose_action_descriptors ? "[#{item.project.name}]" : "[P]" ) link_to_project( item.project, prefs.verbose_action_descriptors ? "[#{item.project.name}]" : "[P]" )
end end
def render_flash def render_flash
render :partial => 'shared/flash', :object => flash render :partial => 'shared/flash', :object => flash
end end
@ -90,7 +90,7 @@ module ApplicationHelper
def time_span_text(date, i18n_text) def time_span_text(date, i18n_text)
return (date ? "#{i18n_text} #{format_date(date)}" : "").html_safe return (date ? "#{i18n_text} #{format_date(date)}" : "").html_safe
end end
def recurrence_time_span(rt) def recurrence_time_span(rt)
case rt.ends_on case rt.ends_on
when "no_end_date" when "no_end_date"
@ -136,11 +136,11 @@ module ApplicationHelper
def link_to_sidebar_item(item) def link_to_sidebar_item(item)
item.is_a?(Project) ? link_to_project( item ) : link_to_context( item ) item.is_a?(Project) ? link_to_project( item ) : link_to_context( item )
end end
def sidebar_html_for_item(item) def sidebar_html_for_item(item)
content_tag(:li, link_to_sidebar_item(item) + " (" + count_undone_todos_phrase(item)+")") content_tag(:li, link_to_sidebar_item(item) + " (" + count_undone_todos_phrase(item)+")")
end end
def sidebar_html_for_list(list) def sidebar_html_for_list(list)
return content_tag(:li, t('sidebar.list_empty')).html_safe if list.empty? return content_tag(:li, t('sidebar.list_empty')).html_safe if list.empty?
return list.inject("") { |html, item| html << sidebar_html_for_item(item) }.html_safe return list.inject("") { |html, item| html << sidebar_html_for_item(item) }.html_safe
@ -190,16 +190,16 @@ module ApplicationHelper
else else
send("#{type}_todos_path") send("#{type}_todos_path")
end end
end end
def determine_done_path def determine_done_path
done_path(controller.controller_name, :done) done_path(controller.controller_name, :done)
end end
def determine_all_done_path def determine_all_done_path
done_path(controller.controller_name, :all_done) done_path(controller.controller_name, :all_done)
end end
def get_list_of_error_messages_for(model) def get_list_of_error_messages_for(model)
if model.errors.any? if model.errors.any?
content_tag(:div, {:id=>"errorExplanation"}) do content_tag(:div, {:id=>"errorExplanation"}) do
@ -209,7 +209,7 @@ module ApplicationHelper
end end
end end
end end
def link_to_delete(type, object, descriptor = sanitize(object.name)) def link_to_delete(type, object, descriptor = sanitize(object.name))
link_to( link_to(
descriptor, descriptor,
@ -239,19 +239,19 @@ module ApplicationHelper
# create a unique object name which can be used in ajax calls returning js # create a unique object name which can be used in ajax calls returning js
# to prevent concurrent calls with same functions to overwrite each other functions # to prevent concurrent calls with same functions to overwrite each other functions
def unique_object_name_for(name) def unique_object_name_for(name)
"#{name}_#{SecureRandom.hex(5)}" "#{name}_#{SecureRandom.hex(5)}"
end end
def js_render(partial, locals = {}, object=nil) def js_render(partial, locals = {}, object=nil)
if object if object
escape_javascript(render(partial: partial, locals: locals, object: object)) escape_javascript(render(partial: partial, locals: locals, object: object))
else else
escape_javascript(render(partial: partial, locals: locals)) escape_javascript(render(partial: partial, locals: locals))
end end
end end
def js_error_messages_for(object) def js_error_messages_for(object)
escape_javascript(get_list_of_error_messages_for(object)) escape_javascript(get_list_of_error_messages_for(object))
end end
end end

View file

@ -7,9 +7,9 @@ module ContextsHelper
link_to_context( context ) link_to_context( context )
end end
end end
def link_to_delete_context(context, descriptor = sanitize(context.name)) def link_to_delete_context(context, descriptor = sanitize(context.name))
link_to_delete(:context, context, descriptor) link_to_delete(:context, context, descriptor)
end end
def link_to_edit_context (context, descriptor = sanitize(context.name)) def link_to_edit_context (context, descriptor = sanitize(context.name))

View file

@ -51,7 +51,7 @@ module DateLabelHelper
def date_html_wrapper def date_html_wrapper
return "" if @date.nil? return "" if @date.nil?
return content_tag(:a, {:title => @prefs.format_date(@date)}) { return content_tag(:a, {:title => @prefs.format_date(@date)}) {
content_tag(:span, {:class => get_color}) { content_tag(:span, {:class => get_color}) {
yield yield
@ -99,7 +99,7 @@ module DateLabelHelper
def due_date_mobile_html def due_date_mobile_html
date_mobile_html_wrapper { @prefs.format_date(@due) } date_mobile_html_wrapper { @prefs.format_date(@due) }
end end
end end
@ -130,4 +130,4 @@ module DateLabelHelper
end end
end end

View file

@ -1,18 +1,18 @@
module FeedlistHelper module FeedlistHelper
def linkoptions(format, options) def linkoptions(format, options)
merge_hashes( {:format => format}, options, user_token_hash) merge_hashes( {:format => format}, options, user_token_hash)
end end
def rss_formatted_link(options = {}) def rss_formatted_link(options = {})
image_tag = image_tag("feed-icon.png", :size => "16X16", :border => 0, :class => "rss-icon") image_tag = image_tag("feed-icon.png", :size => "16X16", :border => 0, :class => "rss-icon")
link_to(image_tag, linkoptions('rss', options), :title => "RSS feed") link_to(image_tag, linkoptions('rss', options), :title => "RSS feed")
end end
def text_formatted_link(options = {}) def text_formatted_link(options = {})
link_to(content_tag(:span, 'TXT', {:class => 'feed', :title => "Plain text feed"}), linkoptions('txt', options)) link_to(content_tag(:span, 'TXT', {:class => 'feed', :title => "Plain text feed"}), linkoptions('txt', options))
end end
def ical_formatted_link(options = {}) def ical_formatted_link(options = {})
link_to(content_tag(:span, 'iCal', {:class=>"feed", :title => "iCal feed"}), linkoptions('ics', options)) link_to(content_tag(:span, 'iCal', {:class=>"feed", :title => "iCal feed"}), linkoptions('ics', options))
end end
@ -32,7 +32,7 @@ module FeedlistHelper
end end
def all_feed_links_for_project(project) def all_feed_links_for_project(project)
all_feed_links(project, :project_id) all_feed_links(project, :project_id)
end end
def all_feed_links_for_context(context) def all_feed_links_for_context(context)
@ -49,5 +49,5 @@ module FeedlistHelper
{ :token => current_user.token } { :token => current_user.token }
end end
end end

View file

@ -1,3 +1,3 @@
module LoginHelper module LoginHelper
end end

View file

@ -1,5 +1,5 @@
module RecurringTodosHelper module RecurringTodosHelper
def recurring_todo_tag_list def recurring_todo_tag_list
tags_except_starred = @recurring_todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} tags_except_starred = @recurring_todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
tag_list = tags_except_starred. tag_list = tags_except_starred.
@ -7,19 +7,19 @@ module RecurringTodosHelper
join('') join('')
return content_tag :span, tag_list.html_safe, :class => "tags" return content_tag :span, tag_list.html_safe, :class => "tags"
end end
def recurring_todo_remote_delete_icon def recurring_todo_remote_delete_icon
link_to( image_tag_for_delete, link_to( image_tag_for_delete,
recurring_todo_path(@recurring_todo), :id => "delete_icon_"+@recurring_todo.id.to_s, recurring_todo_path(@recurring_todo), :id => "delete_icon_"+@recurring_todo.id.to_s,
:class => "icon delete_icon", :title => t('todos.delete_recurring_action_title'), :x_confirm_message => t('todos.delete_recurring_action_confirm', :description => @recurring_todo.description)) :class => "icon delete_icon", :title => t('todos.delete_recurring_action_title'), :x_confirm_message => t('todos.delete_recurring_action_confirm', :description => @recurring_todo.description))
end end
def recurring_todo_remote_star_icon def recurring_todo_remote_star_icon
link_to( image_tag_for_star(@recurring_todo), link_to( image_tag_for_star(@recurring_todo),
toggle_star_recurring_todo_path(@recurring_todo), :id => "star_icon_"+@recurring_todo.id.to_s, toggle_star_recurring_todo_path(@recurring_todo), :id => "star_icon_"+@recurring_todo.id.to_s,
:class => "icon star_item", :title => t('todos.star_action')) :class => "icon star_item", :title => t('todos.star_action'))
end end
def recurring_todo_remote_edit_icon def recurring_todo_remote_edit_icon
if !@recurring_todo.completed? if !@recurring_todo.completed?
str = link_to( image_tag_for_edit(@recurring_todo), str = link_to( image_tag_for_edit(@recurring_todo),
@ -30,7 +30,7 @@ module RecurringTodosHelper
end end
str str
end end
def recurring_todo_remote_toggle_checkbox def recurring_todo_remote_toggle_checkbox
return check_box_tag("check_#{@recurring_todo.id}", toggle_check_recurring_todo_path(@recurring_todo), @recurring_todo.completed?, :class => 'item-checkbox') return check_box_tag("check_#{@recurring_todo.id}", toggle_check_recurring_todo_path(@recurring_todo), @recurring_todo.completed?, :class => 'item-checkbox')
end end

View file

@ -24,7 +24,7 @@ module TodosHelper
def show_grouped_todos(settings = {}) def show_grouped_todos(settings = {})
collection = (@group_view_by == 'context') ? @contexts_to_show : @projects_to_show collection = (@group_view_by == 'context') ? @contexts_to_show : @projects_to_show
render(:partial => collection, :locals => { :settings => settings.reverse_merge!({ render(:partial => collection, :locals => { :settings => settings.reverse_merge!({
:collapsible => true, :collapsible => true,
:show_empty_containers => @show_empty_containers, :show_empty_containers => @show_empty_containers,
:parent_container_type => @group_view_by :parent_container_type => @group_view_by
})}) })})
@ -32,9 +32,9 @@ module TodosHelper
def default_collection_settings def default_collection_settings
{ {
:suppress_context => false, :suppress_context => false,
:suppress_project => false, :suppress_project => false,
:collapsible => false, :collapsible => false,
:append_descriptor => nil, :append_descriptor => nil,
:parent_container_type => nil, :parent_container_type => nil,
:show_empty_containers => true :show_empty_containers => true
@ -45,29 +45,29 @@ module TodosHelper
settings[:container_name] = "completed" settings[:container_name] = "completed"
settings[:link_in_header] = link_to(t('common.show_all'), determine_done_path) settings[:link_in_header] = link_to(t('common.show_all'), determine_done_path)
render :partial => 'todos/collection', render :partial => 'todos/collection',
:object => done_todos, :object => done_todos,
:locals => {:settings => settings.reverse_merge!(default_collection_settings)} :locals => {:settings => settings.reverse_merge!(default_collection_settings)}
end end
def show_completed_todos_for(period, collection) def show_completed_todos_for(period, collection)
settings = { settings = {
:parent_container_type => "completed", :parent_container_type => "completed",
:container_name => "completed_#{period}", :container_name => "completed_#{period}",
:title => t("todos.completed_#{period}"), :title => t("todos.completed_#{period}"),
:show_empty_containers => true :show_empty_containers => true
} }
render :partial => "todos/collection", render :partial => "todos/collection",
:object => collection, :object => collection,
:locals => { :settings => settings} :locals => { :settings => settings}
end end
def show_hidden_todos(hidden_todos, settings={}) def show_hidden_todos(hidden_todos, settings={})
settings[:container_name] = "hidden" settings[:container_name] = "hidden"
render :partial => 'todos/collection', render :partial => 'todos/collection',
:object => hidden_todos, :object => hidden_todos,
:locals => {:settings => settings.reverse_merge!(default_collection_settings)} :locals => {:settings => settings.reverse_merge!(default_collection_settings)}
end end
@ -75,16 +75,16 @@ module TodosHelper
settings[:pending] = pending_todos settings[:pending] = pending_todos
settings[:container_name]="deferred_pending" settings[:container_name]="deferred_pending"
render :partial => "todos/collection", render :partial => "todos/collection",
:object => deferred_todos+pending_todos, :object => deferred_todos+pending_todos,
:locals => {:settings => settings.reverse_merge!(default_collection_settings)} :locals => {:settings => settings.reverse_merge!(default_collection_settings)}
end end
def show_todos_without_project(todos_without_project, settings = {}) def show_todos_without_project(todos_without_project, settings = {})
render :partial => 'todos/collection', render :partial => 'todos/collection',
:object => todos_without_project, :object => todos_without_project,
:locals => {:settings => settings.reverse_merge!({ :locals => {:settings => settings.reverse_merge!({
:collapsible => true, :collapsible => true,
:container_name => "without_project", :container_name => "without_project",
:parent_container_type => "home" :parent_container_type => "home"
}) })
@ -101,9 +101,9 @@ module TodosHelper
settings[:class] += " collapsible" settings[:class] += " collapsible"
end end
content_tag(:div, content_tag(:div,
:class=>settings[:class], :class=>settings[:class],
:id=>settings[:id], :id=>settings[:id],
:style => "display:" + (settings[:show_container] ? "block" : "none")) do :style => "display:" + (settings[:show_container] ? "block" : "none")) do
yield yield
end end
@ -133,10 +133,10 @@ module TodosHelper
end end
def todos_calendar_container(period, collection) def todos_calendar_container(period, collection)
render :partial => 'todos/collection', render :partial => 'todos/collection',
:object => collection, :object => collection,
:locals => {:settings => { :locals => {:settings => {
:collapsible => false, :collapsible => false,
:show_empty_containers => true, :show_empty_containers => true,
:container_name => "#{period}", :container_name => "#{period}",
:title =>t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"), :next_month => l(1.month.from_now, :format => "%B")) :title =>t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"), :next_month => l(1.month.from_now, :format => "%B"))
@ -393,10 +393,10 @@ module TodosHelper
end end
# jquery animations are async, so first collect all animation steps that need # jquery animations are async, so first collect all animation steps that need
# to be run sequential in array animation, then execute them. All steps are # to be run sequential in array animation, then execute them. All steps are
# functions which are passed a function as parameter that should execute the next # functions which are passed a function as parameter that should execute the next
# animation steps. # animation steps.
# if the animation needs to be run inside the namespace of an object, set the # if the animation needs to be run inside the namespace of an object, set the
# object_name to the name of the object and this name will be prepended to each step # object_name to the name of the object and this name will be prepended to each step
def render_animation(animation, object_name=nil) def render_animation(animation, object_name=nil)
object_name += "." unless object_name.nil? # add dot if object_name is given object_name += "." unless object_name.nil? # add dot if object_name is given
@ -431,7 +431,7 @@ module TodosHelper
content_tag(:div, "#{t('common.project')}: #{project_link}") + "\n" + content_tag(:div, "#{t('common.project')}: #{project_link}") + "\n" +
content_tag(:div, "#{t('common.context')}: #{context_link}") content_tag(:div, "#{t('common.context')}: #{context_link}")
end end
# === handle CRUD actions for todos # === handle CRUD actions for todos
def show_todo_on_current_context_page def show_todo_on_current_context_page
@ -440,7 +440,7 @@ module TodosHelper
def todo_should_not_be_hidden_on_context_page def todo_should_not_be_hidden_on_context_page
return !@todo.hidden? || # todo is not hidden --> show return !@todo.hidden? || # todo is not hidden --> show
(@todo.hidden? && @todo.context.hidden?) # todo is hidden, but context is hidden too --> show (@todo.hidden? && @todo.context.hidden?) # todo is hidden, but context is hidden too --> show
end end
def show_todo_on_current_project_page def show_todo_on_current_project_page
@ -502,12 +502,12 @@ module TodosHelper
@tag_was_removed || @tag_was_removed ||
@todo_was_destroyed || @todo_was_destroyed ||
(@todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden || @original_item_was_pending)) (@todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden || @original_item_was_pending))
) )
end end
return false if source_view_is_one_of(:calendar, :done, :all_done) return false if source_view_is_one_of(:calendar, :done, :all_done)
return @remaining_in_context == 0 return @remaining_in_context == 0
end end
def update_needs_to_remove_todo_from_container def update_needs_to_remove_todo_from_container
@ -559,9 +559,9 @@ module TodosHelper
def should_show_empty_container def should_show_empty_container
source_view do |page| source_view do |page|
page.context { return @remaining_in_context == 0 } page.context { return @remaining_in_context == 0 }
end end
return @down_count==0 return @down_count==0
end end
def project_container_id(todo) def project_container_id(todo)
@ -588,7 +588,7 @@ module TodosHelper
end end
def todo_container_empty_id(todo) def todo_container_empty_id(todo)
raise Exception.new, "no todo set in TodosHelper::todo_container_empty_id. You probably did not assign @original_item" if !todo raise Exception.new, "no todo set in TodosHelper::todo_container_empty_id. You probably did not assign @original_item" if !todo
@group_view_by == "project" ? project_container_empty_id(todo) : context_container_empty_id(todo) @group_view_by == "project" ? project_container_empty_id(todo) : context_container_empty_id(todo)
end end
@ -599,7 +599,7 @@ module TodosHelper
return "deferred_pending_container" if !source_view_is(:todo) && (todo.deferred? || todo.pending?) return "deferred_pending_container" if !source_view_is(:todo) && (todo.deferred? || todo.pending?)
return "completed_container" if todo.completed? return "completed_container" if todo.completed?
return project_container_id(todo) if source_view_is_one_of(:todo, :tag, :project, :context) && @group_view_by == 'project' return project_container_id(todo) if source_view_is_one_of(:todo, :tag, :project, :context) && @group_view_by == 'project'
return context_container_id(todo) return context_container_id(todo)
end end
def empty_container_msg_div_id(todo = @todo || @successor) def empty_container_msg_div_id(todo = @todo || @successor)
@ -624,7 +624,7 @@ module TodosHelper
return todo_container_empty_id(todo) return todo_container_empty_id(todo)
} }
page.todo { page.todo {
return todo_container_empty_id(todo) return todo_container_empty_id(todo)
} }
page.deferred { page.deferred {
return todo_container_empty_id(todo) return todo_container_empty_id(todo)

View file

@ -1,6 +1,6 @@
class Context < ActiveRecord::Base class Context < ActiveRecord::Base
has_many :todos, -> { order("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(:project) }, :dependent => :delete_all has_many :todos, -> { order("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(:project) }, :dependent => :delete_all
has_many :recurring_todos, :dependent => :delete_all has_many :recurring_todos, :dependent => :delete_all
belongs_to :user belongs_to :user
@ -15,7 +15,7 @@ class Context < ActiveRecord::Base
include AASM include AASM
aasm :column => :state do aasm :column => :state do
state :active, :initial => true state :active, :initial => true
state :closed state :closed
state :hidden state :hidden

View file

@ -1,9 +1,9 @@
class Dependency < ActiveRecord::Base class Dependency < ActiveRecord::Base
# touch to make sure todo caches for predecessor and successor are invalidated # touch to make sure todo caches for predecessor and successor are invalidated
belongs_to :predecessor, :foreign_key => 'predecessor_id', :class_name => 'Todo', :touch => true belongs_to :predecessor, :foreign_key => 'predecessor_id', :class_name => 'Todo', :touch => true
belongs_to :successor, :foreign_key => 'successor_id', :class_name => 'Todo', :touch => true belongs_to :successor, :foreign_key => 'successor_id', :class_name => 'Todo', :touch => true
end end

View file

@ -1,10 +1,10 @@
class MessageGateway < ActionMailer::Base class MessageGateway < ActionMailer::Base
def receive(email) def receive(email)
user = get_receiving_user_from_email_address(email) user = get_receiving_user_from_email_address(email)
return false if user.nil? return false if user.nil?
return false unless check_sender_is_in_mailmap(user, email) return false unless check_sender_is_in_mailmap(user, email)
context = user.prefs.sms_context context = user.prefs.sms_context
todo_params = get_todo_params(email) todo_params = get_todo_params(email)
@ -14,12 +14,12 @@ class MessageGateway < ActionMailer::Base
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}" Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
todo todo
end end
private private
def get_todo_params(email) def get_todo_params(email)
params = {} params = {}
if email.multipart? if email.multipart?
params[:description] = get_text_or_nil(email.subject) params[:description] = get_text_or_nil(email.subject)
params[:notes] = get_first_text_plain_part(email) params[:notes] = get_first_text_plain_part(email)
@ -33,11 +33,11 @@ class MessageGateway < ActionMailer::Base
end end
end end
params params
end end
def get_receiving_user_from_email_address(email) def get_receiving_user_from_email_address(email)
SITE_CONFIG['email_dispatch'] == 'single_user' ? get_receiving_user_from_env_setting : get_receiving_user_from_mail_header(email) SITE_CONFIG['email_dispatch'] == 'single_user' ? get_receiving_user_from_env_setting : get_receiving_user_from_mail_header(email)
end end
def get_receiving_user_from_env_setting def get_receiving_user_from_env_setting
Rails.logger.info "All received email goes to #{ENV['TRACKS_MAIL_RECEIVER']}" Rails.logger.info "All received email goes to #{ENV['TRACKS_MAIL_RECEIVER']}"
@ -45,7 +45,7 @@ class MessageGateway < ActionMailer::Base
Rails.logger.info "WARNING: Unknown user set for TRACKS_MAIL_RECEIVER (#{ENV['TRACKS_MAIL_RECEIVER']})" if user.nil? Rails.logger.info "WARNING: Unknown user set for TRACKS_MAIL_RECEIVER (#{ENV['TRACKS_MAIL_RECEIVER']})" if user.nil?
return user return user
end end
def get_receiving_user_from_mail_header(email) def get_receiving_user_from_mail_header(email)
user = get_receiving_user_from_sms_email( get_address(email) ) user = get_receiving_user_from_sms_email( get_address(email) )
Rails.logger.info(user.nil? ? "User unknown": "Email belongs to #{user.login}") Rails.logger.info(user.nil? ? "User unknown": "Email belongs to #{user.login}")
@ -61,7 +61,7 @@ class MessageGateway < ActionMailer::Base
user = User.where("preferences.sms_email" => address.strip).includes(:preference).first user = User.where("preferences.sms_email" => address.strip).includes(:preference).first
user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first if user.nil? user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first if user.nil?
return user return user
end end
def check_sender_is_in_mailmap(user, email) def check_sender_is_in_mailmap(user, email)
if user.present? and !sender_is_in_mailmap?(user,email) if user.present? and !sender_is_in_mailmap?(user,email)
@ -69,7 +69,7 @@ class MessageGateway < ActionMailer::Base
return false return false
end end
return true return true
end end
def sender_is_in_mailmap?(user,email) def sender_is_in_mailmap?(user,email)
if SITE_CONFIG['mailmap'].is_a? Hash and SITE_CONFIG['email_dispatch'] == 'to' if SITE_CONFIG['mailmap'].is_a? Hash and SITE_CONFIG['email_dispatch'] == 'to'
@ -89,17 +89,17 @@ class MessageGateway < ActionMailer::Base
def get_decoded_text_or_nil(text) def get_decoded_text_or_nil(text)
return text ? text.decoded.strip : nil return text ? text.decoded.strip : nil
end end
def get_first_text_plain_part(email) def get_first_text_plain_part(email)
# get all parts from multipart/alternative attachments # get all parts from multipart/alternative attachments
parts = get_all_parts(email.parts) parts = get_all_parts(email.parts)
# remove all parts that are not text/plain # remove all parts that are not text/plain
parts.reject{|part| !part.content_type.start_with?("text/plain") } parts.reject{|part| !part.content_type.start_with?("text/plain") }
return parts.count > 0 ? parts[0].decoded.strip : "" return parts.count > 0 ? parts[0].decoded.strip : ""
end end
def get_all_parts(parts) def get_all_parts(parts)
# return a flattened array of parts. If a multipart attachment is found, recurse over its parts # return a flattened array of parts. If a multipart attachment is found, recurse over its parts
all_parts = parts.inject([]) do |set, elem| all_parts = parts.inject([]) do |set, elem|
@ -111,5 +111,5 @@ class MessageGateway < ActionMailer::Base
end end
end end
end end
end end

View file

@ -142,7 +142,7 @@ class Project < ActiveRecord::Base
count = 0 count = 0
CSV.foreach(filename, headers: true) do |row| CSV.foreach(filename, headers: true) do |row|
unless find_by_name_and_user_id row[params[:name].to_i], user.id unless find_by_name_and_user_id row[params[:name].to_i], user.id
project = new project = new
project.name = row[params[:name].to_i] project.name = row[params[:name].to_i]
project.user = user project.user = user
project.description = row[params[:description].to_i] if row[params[:description].to_i].present? project.description = row[params[:description].to_i] if row[params[:description].to_i].present?

View file

@ -119,7 +119,7 @@ class RecurringTodo < ActiveRecord::Base
def remove_from_project! def remove_from_project!
self.project = nil self.project = nil
self.save self.save
end end
def clear_todos_association def clear_todos_association
unless todos.nil? unless todos.nil?
@ -139,4 +139,4 @@ class RecurringTodo < ActiveRecord::Base
pattern.continues_recurring?(previous) pattern.continues_recurring?(previous)
end end
end end

View file

@ -1,6 +1,6 @@
module RecurringTodos module RecurringTodos
class AbstractRecurringTodosBuilder class AbstractRecurringTodosBuilder
attr_reader :mapped_attributes, :pattern attr_reader :mapped_attributes, :pattern
@ -40,7 +40,7 @@ module RecurringTodos
save_collection(:context, :context_id) save_collection(:context, :context_id)
end end
def saved_recurring_todo def saved_recurring_todo
raise(Exception.new, @recurring_todo.valid? ? "Recurring todo was not saved yet" : "Recurring todos was not saved because of validation errors") unless @saved raise(Exception.new, @recurring_todo.valid? ? "Recurring todo was not saved yet" : "Recurring todos was not saved because of validation errors") unless @saved
@recurring_todo @recurring_todo
@ -103,7 +103,7 @@ module RecurringTodos
# should return period specific selector like yearly_selector or daily_selector # should return period specific selector like yearly_selector or daily_selector
def selector_key def selector_key
raise Exception.new, "selector_key should be overridden in subclass of AbstractRecurringTodosBuilder" raise Exception.new, "selector_key should be overridden in subclass of AbstractRecurringTodosBuilder"
end end
def get_selector(key) def get_selector(key)
return nil if key.nil? return nil if key.nil?
@ -149,4 +149,4 @@ module RecurringTodos
end end
end end

View file

@ -165,7 +165,7 @@ module RecurringTodos
get_show_from_date(previous) <= self.end_date get_show_from_date(previous) <= self.end_date
end end
end end
private private
# Determine start date to calculate next date for recurring todo which # Determine start date to calculate next date for recurring todo which
@ -196,7 +196,7 @@ module RecurringTodos
else else
return find_xth_day_of_month(x, weekday, month, year) return find_xth_day_of_month(x, weekday, month, year)
end end
end end
def find_last_day_x_of_month(weekday, month, year) def find_last_day_x_of_month(weekday, month, year)
# count backwards. use UTC to avoid strange timezone oddities # count backwards. use UTC to avoid strange timezone oddities
@ -207,7 +207,7 @@ module RecurringTodos
end end
# convert back to local timezone # convert back to local timezone
Time.zone.local(last_day.year, last_day.month, last_day.day) Time.zone.local(last_day.year, last_day.month, last_day.day)
end end
def find_xth_day_of_month(x, weekday, month, year) def find_xth_day_of_month(x, weekday, month, year)
# 1-4th -> count upwards last -> count backwards. use UTC to avoid strange # 1-4th -> count upwards last -> count backwards. use UTC to avoid strange
@ -224,7 +224,7 @@ module RecurringTodos
end end
# convert back to local timezone # convert back to local timezone
Time.zone.local(start.year, start.month, start.day) Time.zone.local(start.year, start.month, start.day)
end end
end end
end end

View file

@ -18,7 +18,7 @@ module RecurringTodos
end end
def only_work_days?(daily_selector) def only_work_days?(daily_selector)
{ 'daily_every_x_day' => false, { 'daily_every_x_day' => false,
'daily_every_work_day' => true}[daily_selector] 'daily_every_work_day' => true}[daily_selector]
end end
@ -32,4 +32,4 @@ module RecurringTodos
end end
end end

View file

@ -41,7 +41,7 @@ module RecurringTodos
return start + 2.day if start.wday() == 6 # saturday return start + 2.day if start.wday() == 6 # saturday
return start + 1.day if start.wday() == 0 # sunday return start + 1.day if start.wday() == 0 # sunday
return start return start
else else
# if there was no previous todo, do not add n: the first todo starts on # if there was no previous todo, do not add n: the first todo starts on
# today or on start_from # today or on start_from
return previous == nil ? start : start+every_x_days.day-1.day return previous == nil ? start : start+every_x_days.day-1.day
@ -49,4 +49,4 @@ module RecurringTodos
end end
end end
end end

View file

@ -9,8 +9,8 @@ module RecurringTodos
def attributes_to_filter def attributes_to_filter
%w{ %w{
monthly_selector monthly_every_x_day monthly_every_x_month monthly_selector monthly_every_x_day monthly_every_x_month
monthly_every_x_month2 monthly_every_xth_day monthly_day_of_week monthly_every_x_month2 monthly_every_xth_day monthly_day_of_week
} }
end end
@ -27,7 +27,7 @@ module RecurringTodos
def get_recurrence_selector def get_recurrence_selector
@selector=='monthly_every_x_day' ? 0 : 1 @selector=='monthly_every_x_day' ? 0 : 1
end end
def get_every_other2 def get_every_other2
get_recurrence_selector == 0 ? 'monthly_every_x_month' : 'monthly_every_x_month2' get_recurrence_selector == 0 ? 'monthly_every_x_month' : 'monthly_every_x_month2'

View file

@ -94,7 +94,7 @@ module RecurringTodos
start = Time.utc(start.year, start.month, start.day)+n.months start = Time.utc(start.year, start.month, start.day)+n.months
end end
Time.zone.local(start.year, start.month, every_x_day) Time.zone.local(start.year, start.month, every_x_day)
end end
def find_relative_day_of_month(start, n) def find_relative_day_of_month(start, n)
the_next = get_xth_day_of_month(every_xth_day, day_of_week, start.month, start.year) the_next = get_xth_day_of_month(every_xth_day, day_of_week, start.month, start.year)
@ -113,7 +113,7 @@ module RecurringTodos
# support 5th day of the month, we need to handle this case # support 5th day of the month, we need to handle this case
the_next = get_xth_day_of_month(every_xth_day, day_of_week, the_next.month, the_next.year) the_next = get_xth_day_of_month(every_xth_day, day_of_week, the_next.month, the_next.year)
end end
the_next the_next
end end
def recurrence_pattern_for_specific_day def recurrence_pattern_for_specific_day
@ -132,11 +132,11 @@ module RecurringTodos
I18n.t('common.month') I18n.t('common.month')
end end
I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months', I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months',
x: xth(every_xth_day), x: xth(every_xth_day),
day: day_of_week_as_text(day_of_week), day: day_of_week_as_text(day_of_week),
n_months: n_months) n_months: n_months)
end end
end end
end end

View file

@ -15,7 +15,7 @@ module RecurringTodos
mapping = map(mapping, :every_other1, 'weekly_every_x_week') mapping = map(mapping, :every_other1, 'weekly_every_x_week')
{ monday: 1, tuesday: 2, wednesday: 3, thursday: 4, friday: 5, saturday: 6, sunday: 0 } { monday: 1, tuesday: 2, wednesday: 3, thursday: 4, friday: 5, saturday: 6, sunday: 0 }
.each do |day, index| .each do |day, index|
mapping = map_day(mapping, :every_day, "weekly_return_#{day}", index) mapping = map_day(mapping, :every_day, "weekly_return_#{day}", index)
end end

View file

@ -75,12 +75,12 @@ module RecurringTodos
def find_first_day_in_this_week(start) def find_first_day_in_this_week(start)
# check if there are any days left this week for the next todo # check if there are any days left this week for the next todo
start.wday().upto 6 do |i| start.wday().upto 6 do |i|
return start + (i-start.wday()).days if on_xday(i) return start + (i-start.wday()).days if on_xday(i)
end end
-1 -1
end end
end end
end end

View file

@ -8,8 +8,8 @@ module RecurringTodos
end end
def attributes_to_filter def attributes_to_filter
%w{ yearly_selector yearly_month_of_year yearly_month_of_year2 %w{ yearly_selector yearly_month_of_year yearly_month_of_year2
yearly_every_x_day yearly_every_xth_day yearly_day_of_week yearly_every_x_day yearly_every_xth_day yearly_day_of_week
} }
end end
@ -34,7 +34,7 @@ module RecurringTodos
def get_recurrence_selector def get_recurrence_selector
@selector=='yearly_every_x_day' ? 0 : 1 @selector=='yearly_every_x_day' ? 0 : 1
end end
def get_every_other2 def get_every_other2
{ 0 => :yearly_month_of_year, 1 => :yearly_month_of_year2 }[get_recurrence_selector] { 0 => :yearly_month_of_year, 1 => :yearly_month_of_year2 }[get_recurrence_selector]

View file

@ -37,9 +37,9 @@ module RecurringTodos
I18n.t("todos.recurrence.pattern.every_year_on", :date => date_as_month_day) I18n.t("todos.recurrence.pattern.every_year_on", :date => date_as_month_day)
else else
I18n.t("todos.recurrence.pattern.every_year_on", I18n.t("todos.recurrence.pattern.every_year_on",
:date => I18n.t("todos.recurrence.pattern.the_xth_day_of_month", :date => I18n.t("todos.recurrence.pattern.the_xth_day_of_month",
:x => xth(every_xth_day), :x => xth(every_xth_day),
:day => day_of_week_as_text(day_of_week), :day => day_of_week_as_text(day_of_week),
:month => month_of_year_as_text(month_of_year) :month => month_of_year_as_text(month_of_year)
)) ))
end end
@ -57,7 +57,7 @@ module RecurringTodos
validate_not_blank(day_of_week, "The day of the week may not be empty for recurrence setting") validate_not_blank(day_of_week, "The day of the week may not be empty for recurrence setting")
else else
raise "unexpected value of recurrence selector '#{recurrence_selector}'" raise "unexpected value of recurrence selector '#{recurrence_selector}'"
end end
end end
def get_next_date(previous) def get_next_date(previous)
@ -105,5 +105,5 @@ module RecurringTodos
the_next the_next
end end
end end
end end

View file

@ -1,8 +1,8 @@
class Tag < ActiveRecord::Base class Tag < ActiveRecord::Base
has_many :taggings has_many :taggings
has_many :taggable, :through => :taggings has_many :taggable, :through => :taggings
DELIMITER = "," # Controls how to split and join tagnames from strings. You may need to change the <tt>validates_format_of parameters</tt> if you change this. DELIMITER = "," # Controls how to split and join tagnames from strings. You may need to change the <tt>validates_format_of parameters</tt> if you change this.
JOIN_DELIMITER = ", " JOIN_DELIMITER = ", "
@ -10,9 +10,9 @@ class Tag < ActiveRecord::Base
# rescue the ActiveRecord database constraint errors instead. # rescue the ActiveRecord database constraint errors instead.
validates_presence_of :name validates_presence_of :name
validates_uniqueness_of :name, :case_sensitive => false validates_uniqueness_of :name, :case_sensitive => false
before_create :before_create before_create :before_create
# Callback to strip extra spaces from the tagname before saving it. If you # Callback to strip extra spaces from the tagname before saving it. If you
# allow tags to be renamed later, you might want to use the # allow tags to be renamed later, you might want to use the
# <tt>before_save</tt> callback instead. # <tt>before_save</tt> callback instead.

View file

@ -2,16 +2,16 @@
# The Tagging join model. # The Tagging join model.
class Tagging < ActiveRecord::Base class Tagging < ActiveRecord::Base
belongs_to :tag belongs_to :tag
belongs_to :taggable, :polymorphic => true, :touch => true belongs_to :taggable, :polymorphic => true, :touch => true
after_destroy :delete_orphaned_tag after_destroy :delete_orphaned_tag
private private
def delete_orphaned_tag def delete_orphaned_tag
tag.destroy if tag and tag.taggings.count == 0 tag.destroy if tag and tag.taggings.count == 0
end end
end end

View file

@ -70,7 +70,7 @@ class Todo < ActiveRecord::Base
aasm :column => :state do aasm :column => :state do
state :active state :active
state :project_hidden state :project_hidden
state :completed, :before_enter => Proc.new { |t| t.completed_at = Time.zone.now }, :before_exit => Proc.new { |t| t.completed_at = nil} state :completed, :before_enter => Proc.new { |t| t.completed_at = Time.zone.now }, :before_exit => Proc.new { |t| t.completed_at = nil}
state :deferred, :before_exit => Proc.new { |t| t[:show_from] = nil } state :deferred, :before_exit => Proc.new { |t| t[:show_from] = nil }
@ -396,11 +396,11 @@ class Todo < ActiveRecord::Base
def self.import(filename, params, user) def self.import(filename, params, user)
default_context = user.contexts.order('id').first default_context = user.contexts.order('id').first
count = 0 count = 0
CSV.foreach(filename, headers: true) do |row| CSV.foreach(filename, headers: true) do |row|
unless find_by_description_and_user_id row[params[:description].to_i], user.id unless find_by_description_and_user_id row[params[:description].to_i], user.id
todo = new todo = new
todo.user = user todo.user = user
todo.description = row[params[:description].to_i].truncate MAX_DESCRIPTION_LENGTH todo.description = row[params[:description].to_i].truncate MAX_DESCRIPTION_LENGTH
todo.context = Context.find_by_name_and_user_id(row[params[:context].to_i], user.id) || default_context todo.context = Context.find_by_name_and_user_id(row[params[:context].to_i], user.id) || default_context
@ -408,7 +408,7 @@ class Todo < ActiveRecord::Base
todo.state = row[params[:completed_at].to_i].present? ? 'completed' : 'active' todo.state = row[params[:completed_at].to_i].present? ? 'completed' : 'active'
todo.notes = row[params[:notes].to_i].truncate MAX_NOTES_LENGTH if row[params[:notes].to_i].present? todo.notes = row[params[:notes].to_i].truncate MAX_NOTES_LENGTH if row[params[:notes].to_i].present?
todo.created_at = row[params[:created_at].to_i] if row[params[:created_at].to_i].present? todo.created_at = row[params[:created_at].to_i] if row[params[:created_at].to_i].present?
todo.due = row[params[:due].to_i] todo.due = row[params[:due].to_i]
todo.completed_at = row[params[:completed_at].to_i] if row[params[:completed_at].to_i].present? todo.completed_at = row[params[:completed_at].to_i] if row[params[:completed_at].to_i].present?
todo.save! todo.save!
count += 1 count += 1

View file

@ -4,7 +4,7 @@ require 'bcrypt'
class User < ActiveRecord::Base class User < ActiveRecord::Base
# Virtual attribute for the unencrypted password # Virtual attribute for the unencrypted password
attr_accessor :password attr_accessor :password
#for will_paginate plugin #for will_paginate plugin
cattr_accessor :per_page cattr_accessor :per_page
@@per_page = 5 @@per_page = 5

View file

@ -4,7 +4,7 @@ VERSION:2.0
CALSCALE:GREGORIAN CALSCALE:GREGORIAN
METHOD:PUBLISH METHOD:PUBLISH
X-WR-CALNAME:Tracks X-WR-CALNAME:Tracks
<% for todo in @due_all <% for todo in @due_all
due_date = todo.due due_date = todo.due
overdue_text = "" overdue_text = ""
if due_date.at_midnight < Time.zone.now.at_midnight if due_date.at_midnight < Time.zone.now.at_midnight

View file

@ -4,16 +4,16 @@
# rendering of "due in x days" that change without touching updated at of the todo # rendering of "due in x days" that change without touching updated at of the todo
cache [context, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do cache [context, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do
-%> -%>
<%= <%=
render :partial => 'todos/collection', render :partial => 'todos/collection',
:object => @not_done, :object => @not_done,
:locals => { :settings => { :locals => { :settings => {
:id => "c#{context.id}", :id => "c#{context.id}",
:collapsible => settings[:collapsible], :collapsible => settings[:collapsible],
:container_name => 'context', :container_name => 'context',
:title => show_context_name(context), :title => show_context_name(context),
:show_empty_containers => settings[:show_empty_containers], :show_empty_containers => settings[:show_empty_containers],
:parent_container_type => settings[:parent_container_type] :parent_container_type => settings[:parent_container_type]
}} }}
%> %>
<% end %> <% end %>

View file

@ -3,11 +3,11 @@
<span id="<%= state %>-contexts-count" class="badge"><%= context_state_group.length %></span> <span id="<%= state %>-contexts-count" class="badge"><%= context_state_group.length %></span>
<%= t("states.contexts."+ state) %> <%= t("states.contexts."+ state) %>
</h2> </h2>
<div id="<%= state%>-contexts-empty-nd" style="<%= no_contexts ? 'display:block' : 'display:none'%>"> <div id="<%= state%>-contexts-empty-nd" style="<%= no_contexts ? 'display:block' : 'display:none'%>">
<div class="message"><p><%= t('contexts.no_contexts_' + state) %></p></div> <div class="message"><p><%= t('contexts.no_contexts_' + state) %></p></div>
</div> </div>
<div id="list-contexts-<%= state %>"> <div id="list-contexts-<%= state %>">
<%= render :partial => 'context_listing', :collection => context_state_group %> <%= render :partial => 'context_listing', :collection => context_state_group %>
</div> </div>

View file

@ -1,4 +1,4 @@
<% <%
suffix_completed = t('contexts.last_completed_in_context', :number=>prefs.show_number_completed) suffix_completed = t('contexts.last_completed_in_context', :number=>prefs.show_number_completed)
deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'context'} deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'context'}
done_todo_options = {:append_descriptor => suffix_completed, :suppress_context => true, :parent_container_type => 'context'} done_todo_options = {:append_descriptor => suffix_completed, :suppress_context => true, :parent_container_type => 'context'}
@ -7,16 +7,16 @@
<div id="display_box"> <div id="display_box">
<%= empty_message_holder("not_done_context", @not_done_todos.empty?) %> <%= empty_message_holder("not_done_context", @not_done_todos.empty?) %>
<%= show_grouped_todos({:collapsible => false, :show_empty_containers => false, :parent_container_type => 'context'}) %> <%= show_grouped_todos({:collapsible => false, :show_empty_containers => false, :parent_container_type => 'context'}) %>
<% if @group_view_by == 'project' -%> <% if @group_view_by == 'project' -%>
<%= show_todos_without_project(@todos_without_project, {:collapsible => false, :parent_container_type => 'context', :title_param => @context.name}) -%> <%= show_todos_without_project(@todos_without_project, {:collapsible => false, :parent_container_type => 'context', :title_param => @context.name}) -%>
<% end -%> <% end -%>
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %> <%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %> <%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
</div> </div>
<div id="input_box"> <div id="input_box">

View file

@ -1,4 +1,4 @@
<%- <%-
object_name = unique_object_name_for("update_context_#{@context.id}") object_name = unique_object_name_for("update_context_#{@context.id}")
-%> -%>
var <%=object_name%> = { var <%=object_name%> = {
@ -47,4 +47,4 @@ var <%=object_name%> = {
<% end -%> <% end -%>
} }
<%=object_name%>.animate(); <%=object_name%>.animate();

View file

@ -1,11 +1,11 @@
<h3>Map fields to be imported<h3> <h3>Map fields to be imported<h3>
<%= form_tag csv_import_data_path do %> <%= form_tag csv_import_data_path do %>
<% @labels.each do |l| %> <% @labels.each do |l| %>
<%= label_tag l %>: <%= label_tag l %>:
<%= select_tag(l, options_for_select(@headers) ) %> <%= select_tag(l, options_for_select(@headers) ) %>
<br> <br>
<% end %> <% end %>
<%= hidden_field_tag :file, @filename %> <%= hidden_field_tag :file, @filename %>
<%= hidden_field_tag :import_to, @import_to %> <%= hidden_field_tag :import_to, @import_to %>
<%= submit_tag "Import" %> <%= submit_tag "Import" %>
<% end %> <% end %>

View file

@ -10,9 +10,9 @@
<br><br> <br><br>
<%= file_field_tag :file %> <%= file_field_tag :file %>
<%= submit_tag "Upload", :id => "upload_form_submit" %> <%= submit_tag "Upload", :id => "upload_form_submit" %>
<% end %> <% end %>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -31,6 +31,6 @@
<td>XML-Datei mit all Ihren Aktionen, Umgebungen, Projekten, Tags und Notizen</td> <td>XML-Datei mit all Ihren Aktionen, Umgebungen, Projekten, Tags und Notizen</td>
<td><%= link_to "XML file (actions only)", :controller => 'data', :action => 'xml_export' %></td> <td><%= link_to "XML file (actions only)", :controller => 'data', :action => 'xml_export' %></td>
</tr> </tr>
</table> </table>
</div><!-- End of feeds --> </div><!-- End of feeds -->
</div> </div>

View file

@ -28,7 +28,7 @@ tell application "Mail"
end tell end tell
on importMessage(theMessage) on importMessage(theMessage)
-- Get the info from the email message -- Get the info from the email message
tell application "Mail" tell application "Mail"
try try
@ -36,37 +36,37 @@ on importMessage(theMessage)
set theSubject to subject of theMessage set theSubject to subject of theMessage
if theSubject is equal to "" then set theSubject to emptySubject if theSubject is equal to "" then set theSubject to emptySubject
set theMessageId to message id of theMessage set theMessageId to message id of theMessage
-- Construct the description string from the email info -- Construct the description string from the email info
set myDesc to "Email " & theSender & " about " & theSubject set myDesc to "Email " & theSender & " about " & theSubject
-- Trim the string to 100 characters otherwise it won't validate -- Trim the string to 100 characters otherwise it won't validate
if length of myDesc > 100 then if length of myDesc > 100 then
set myDesc to characters 1 thru 100 of myDesc set myDesc to characters 1 thru 100 of myDesc
end if end if
set myNote to "message://<" & theMessageId & ">" set myNote to "message://<" & theMessageId & ">"
end try end try
end tell end tell
-- Now send all that info to Tracks -- Now send all that info to Tracks
-- Edit the URL of your Tracks installation if necessary" -- Edit the URL of your Tracks installation if necessary"
tell application "<%= root_url %>backend/api" tell application "<%= root_url %>backend/api"
set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc, myNote}} set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, myDesc, myNote}}
end tell end tell
(* Growl support - comment out or delete this section if (* Growl support - comment out or delete this section if
you don't have Growl *) you don't have Growl *)
tell application "GrowlHelperApp" tell application "GrowlHelperApp"
set the allNotificationsList to ¬ set the allNotificationsList to ¬
{"Tracks Notification"} {"Tracks Notification"}
-- Make a list of the notifications -- Make a list of the notifications
-- that will be enabled by default. -- that will be enabled by default.
-- Those not enabled by default can be enabled later -- Those not enabled by default can be enabled later
-- in the 'Applications' tab of the growl prefpane. -- in the 'Applications' tab of the growl prefpane.
set the enabledNotificationsList to ¬ set the enabledNotificationsList to ¬
{"Tracks Notification"} {"Tracks Notification"}
-- Register our script with growl. -- Register our script with growl.
-- You can optionally (as here) set a default icon -- You can optionally (as here) set a default icon
-- for this script's notifications. -- for this script's notifications.
@ -78,5 +78,5 @@ on importMessage(theMessage)
notify with name "Tracks Notification" title "New action sent to Tracks" description growlDescription application name "Tracks Applescript" icon of application "Script Editor.app" notify with name "Tracks Notification" title "New action sent to Tracks" description growlDescription application name "Tracks Applescript" icon of application "Script Editor.app"
end tell end tell
(* End of Growl section *) (* End of Growl section *)
end importMessage end importMessage

View file

@ -1,10 +1,10 @@
using terms from application "Quicksilver" using terms from application "Quicksilver"
on process text ThisClipping on process text ThisClipping
set myUsername to "<%= current_user.login %>" set myUsername to "<%= current_user.login %>"
set myToken to "<%= current_user.token %>" set myToken to "<%= current_user.token %>"
set myContextID to <%= context.id %> (* <%= context.name %> *) set myContextID to <%= context.id %> (* <%= context.name %> *)
tell application "<%= root_url %>backend/api" tell application "<%= root_url %>backend/api"
set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, ThisClipping}} set returnValue to call xmlrpc {method name:"NewTodo", parameters:{myUsername, myToken, myContextID, ThisClipping}}
end tell end tell
@ -12,4 +12,4 @@ using terms from application "Quicksilver"
show notification "Tracks: action added." show notification "Tracks: action added."
end tell end tell
end process text end process text
end using terms from end using terms from

View file

@ -5,9 +5,9 @@ xml.OpenSearchDescription 'xmlns' => "http://a9.com/-/spec/opensearch/1.1/" do
xml.ShortName Tracks xml.ShortName Tracks
xml.Description t('integrations.opensearch_description') xml.Description t('integrations.opensearch_description')
xml.InputEncoding 'UTF-8' xml.InputEncoding 'UTF-8'
xml.Image("data:image/x-icon;base64," + @icon_data, xml.Image("data:image/x-icon;base64," + @icon_data,
'width' => '16', 'height' => '16') 'width' => '16', 'height' => '16')
xml.Url 'type' => 'text/html', 'method' => 'GET', xml.Url 'type' => 'text/html', 'method' => 'GET',
'template' => url_for(:controller => 'search', :action => 'results', 'template' => url_for(:controller => 'search', :action => 'results',
:only_path => false) + '?search={searchTerms}' :only_path => false) + '?search={searchTerms}'
end end

View file

@ -56,7 +56,7 @@
<ul> <ul>
<li><%= navigation_link( t('common.contexts'), contexts_path, {:accesskey=>"c", :title=>t('layouts.navigation.contexts_title')} ) %></li> <li><%= navigation_link( t('common.contexts'), contexts_path, {:accesskey=>"c", :title=>t('layouts.navigation.contexts_title')} ) %></li>
<li><%= navigation_link( t('common.notes'), notes_path, {:accesskey => "o", :title => t('layouts.navigation.notes_title')} ) %></li> <li><%= navigation_link( t('common.notes'), notes_path, {:accesskey => "o", :title => t('layouts.navigation.notes_title')} ) %></li>
<li><%= navigation_link( t('common.review'), review_path, {:accesskey => "r", :title => t('layouts.navigation.review_title')} ) %></li> <li><%= navigation_link( t('common.review'), review_path, {:accesskey => "r", :title => t('layouts.navigation.review_title')} ) %></li>
<li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li> <li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li>
</ul> </ul>
</li> </li>

View file

@ -1,7 +1,7 @@
<% note = notes_summary -%> <% note = notes_summary -%>
<div class="note_wrapper" id="<%= dom_id(note) %>"> <div class="note_wrapper" id="<%= dom_id(note) %>">
<div class="note_link"> <div class="note_link">
<%= link_to( <%= link_to(
image_tag("blank.png", :border => 0), image_tag("blank.png", :border => 0),
note, note,
:title => t('notes.show_note_title'), :title => t('notes.show_note_title'),

View file

@ -7,16 +7,16 @@
<%= form_for(@prefs) do %> <%= form_for(@prefs) do %>
<div id="tabs"> <div id="tabs">
<ul> <ul>
<li><a href="#tabs-1"><%= t('preferences.tabs.profile')%></a></li> <li><a href="#tabs-1"><%= t('preferences.tabs.profile')%></a></li>
<li><a href="#tabs-2"><%= t('preferences.tabs.authentication')%></a></li> <li><a href="#tabs-2"><%= t('preferences.tabs.authentication')%></a></li>
<li><a href="#tabs-3"><%= t('preferences.tabs.date_and_time')%></a></li> <li><a href="#tabs-3"><%= t('preferences.tabs.date_and_time')%></a></li>
<li><a href="#tabs-4"><%= t('preferences.tabs.tracks_behavior')%></a></li> <li><a href="#tabs-4"><%= t('preferences.tabs.tracks_behavior')%></a></li>
</ul> </ul>
<div id="tabs-1"><%= render :partial => 'profile'%></div> <div id="tabs-1"><%= render :partial => 'profile'%></div>
<div id="tabs-2"><%= render :partial => 'authentication'%></div> <div id="tabs-2"><%= render :partial => 'authentication'%></div>
<div id="tabs-3"><%= render :partial => 'date_and_time'%></div> <div id="tabs-3"><%= render :partial => 'date_and_time'%></div>
<div id="tabs-4"><%= render :partial => 'tracks_behavior'%></div> <div id="tabs-4"><%= render :partial => 'tracks_behavior'%></div>
</div> </div>
<br/> <br/>
@ -24,4 +24,4 @@
<button type="submit" id="prefs_submit"><%= t('common.update') %></button> <button type="submit" id="prefs_submit"><%= t('common.update') %></button>
<% end %> <% end %>
</div> </div>

View file

@ -2,20 +2,20 @@
@not_done = @not_done_todos.select {|t| t.project_id == project.id } @not_done = @not_done_todos.select {|t| t.project_id == project.id }
# invalidate the cache every day because of staleness or # invalidate the cache every day because of staleness or
# rendering of "due in x days" that change without touching updated at of the todo # rendering of "due in x days" that change without touching updated at of the todo
cache [project, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do cache [project, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do
-%> -%>
<%= <%=
title = source_view_is(:project) ? t('projects.actions_in_project_title') : show_project_name(project) title = source_view_is(:project) ? t('projects.actions_in_project_title') : show_project_name(project)
render(:partial => 'todos/collection', render(:partial => 'todos/collection',
:object => @not_done, :object => @not_done,
:locals => { :settings => { :locals => { :settings => {
:id => "p#{project.id}", :id => "p#{project.id}",
:collapsible => settings[:collapsible], :collapsible => settings[:collapsible],
:title => title, :title => title,
:container_name => 'project', :container_name => 'project',
:show_empty_containers => settings[:show_empty_containers], :show_empty_containers => settings[:show_empty_containers],
:parent_container_type => settings[:parent_container_type] :parent_container_type => settings[:parent_container_type]
}}) }})
%> %>
<% end -%> <% end -%>

View file

@ -1,6 +1,6 @@
<% <%
paginate_options = { paginate_options = {
:class => :add_note_link, :class => :add_note_link,
:previous_label => '&laquo; '+ t('common.previous'), :previous_label => '&laquo; '+ t('common.previous'),
:next_label => t('common.next')+' &raquo;', :next_label => t('common.next')+' &raquo;',
:inner_window => 2 :inner_window => 2
@ -10,7 +10,7 @@
<div id="projects-empty-nd" style="<%= @no_projects ? 'display:block' : 'display:none'%>"> <div id="projects-empty-nd" style="<%= @no_projects ? 'display:block' : 'display:none'%>">
<div class="message"><p><%= t('projects.no_projects') %></p></div> <div class="message"><p><%= t('projects.no_projects') %></p></div>
</div> </div>
<div class="project-state-group" id="list-completed-projects-container" <%= " style=\"display:none\"" if @no_projects %>> <div class="project-state-group" id="list-completed-projects-container" <%= " style=\"display:none\"" if @no_projects %>>
<div class="paginate_header"><%= will_paginate @projects, paginate_options %></div> <div class="paginate_header"><%= will_paginate @projects, paginate_options %></div>
<h2> <h2>
@ -34,4 +34,4 @@
:id => "completed_actionize_link", :class => "actionize_link", :title => t('common.sort.by_task_count_title'), :x_confirm_message => t('common.sort.by_task_count_title_confirm')) %> :id => "completed_actionize_link", :class => "actionize_link", :title => t('common.sort.by_task_count_title'), :x_confirm_message => t('common.sort.by_task_count_title_confirm')) %>
</div> </div>
</div> </div>
</div> </div>

View file

@ -4,7 +4,7 @@
selector_project = "div##{dom_id(@project)}" selector_project = "div##{dom_id(@project)}"
selector_project = "div.project-edit-current " + selector_project unless @source_view=="project" selector_project = "div.project-edit-current " + selector_project unless @source_view=="project"
object_name = unique_object_name_for("edit_project_#{@project.id}") object_name = unique_object_name_for("edit_project_#{@project.id}")
-%> -%>
var <%=object_name%> = { var <%=object_name%> = {
animate: function() { animate: function() {
<%=object_name%>.replace_project_with_edit_form(); <%=object_name%>.replace_project_with_edit_form();
@ -28,4 +28,4 @@ var <%=object_name%> = {
} }
} }
<%=object_name%>.animate(); <%=object_name%>.animate();

View file

@ -1,8 +1,8 @@
<% <%
deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'project'} deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'project'}
done_todo_options = { done_todo_options = {
:append_descriptor => t('projects.last_completed_in_project', :number=>prefs.show_number_completed), :append_descriptor => t('projects.last_completed_in_project', :number=>prefs.show_number_completed),
:suppress_project => true, :suppress_project => true,
:parent_container_type => 'project' :parent_container_type => 'project'
} }
if @not_done_todos.count == 0 if @not_done_todos.count == 0
@ -22,7 +22,7 @@
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %> <%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %> <%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
<div class="container"> <div class="container">
<div id="notes"> <div id="notes">
<div class="add_note_link"><%= link_to t('projects.add_note'), '#' %> </div> <div class="add_note_link"><%= link_to t('projects.add_note'), '#' %> </div>
@ -43,4 +43,4 @@
<div id="input_box"> <div id="input_box">
<%= render :partial => "shared/add_new_item_form" %> <%= render :partial => "shared/add_new_item_form" %>
<%= render :file => "sidebar/sidebar" %> <%= render :file => "sidebar/sidebar" %>
</div> </div>

View file

@ -1,4 +1,4 @@
<%- <%-
object_name = unique_object_name_for("update_project_#{@project.id}") object_name = unique_object_name_for("update_project_#{@project.id}")
-%> -%>
var <%=object_name%> = { var <%=object_name%> = {
@ -9,7 +9,7 @@ var <%=object_name%> = {
html_for_error_messages: function() { html_for_error_messages: function() {
return "<%= js_error_messages_for(@project) %>"; return "<%= js_error_messages_for(@project) %>";
} }
<%- <%-
else else
-%> -%>
animate: function() { animate: function() {
@ -46,7 +46,7 @@ var <%=object_name%> = {
}, },
remove_project_edit_form: function() { remove_project_edit_form: function() {
<%- <%-
# do not remove() edit form as this will remove the DIV # do not remove() edit form as this will remove the DIV
# that is needed to replace with the new form, so only empty the DIV # that is needed to replace with the new form, so only empty the DIV
-%> -%>
$('#<%=dom_id(@project, 'edit')%>').hide(500, function() { $('#<%=dom_id(@project, 'edit')%>').hide(500, function() {
@ -95,4 +95,4 @@ var <%=object_name%> = {
<% end # if @saved -%> <% end # if @saved -%>
} }
<%=object_name%>.animate(); <%=object_name%>.animate();

View file

@ -1,6 +1,6 @@
<% <%
paginate_options = { paginate_options = {
:class => :add_note_link, :class => :add_note_link,
:previous_label => '&laquo; '+ t('common.previous'), :previous_label => '&laquo; '+ t('common.previous'),
:next_label => t('common.next')+' &raquo;', :next_label => t('common.next')+' &raquo;',
:inner_window => 2 :inner_window => 2
@ -21,4 +21,4 @@
</div> </div>
<div class="paginate_footer"><%= will_paginate @completed_recurring_todos, paginate_options %></div> <div class="paginate_footer"><%= will_paginate @completed_recurring_todos, paginate_options %></div>
</div> </div>
</div> </div>

View file

@ -2,10 +2,10 @@
var <%=object_name%> = { var <%=object_name%> = {
animate: function() { animate: function() {
$('#edit-recurring-todo').html(<%=object_name%>.html_for_edit_form()); $('#edit-recurring-todo').html(<%=object_name%>.html_for_edit_form());
$('#edit-recurring-todo').dialog( "open" ); $('#edit-recurring-todo').dialog( "open" );
}, },
html_for_edit_form: function() { html_for_edit_form: function() {
return "<%= js_render('edit_form') %>"; return "<%= js_render('edit_form') %>";
} }
} }
<%=object_name%>.animate(); <%=object_name%>.animate();

View file

@ -2,7 +2,7 @@
TracksPages.page_error('<%= t('todos.error_completing_todo', :description => @recurring_todo.description) %>'); TracksPages.page_error('<%= t('todos.error_completing_todo', :description => @recurring_todo.description) %>');
<%- else <%- else
object_name = unique_object_name_for("toggle_check_rec") object_name = unique_object_name_for("toggle_check_rec")
-%> -%>
var <%=object_name%> = { var <%=object_name%> = {
animate: function() { animate: function() {
TracksPages.set_page_badge(<%= @down_count %>); TracksPages.set_page_badge(<%= @down_count %>);
@ -16,7 +16,7 @@ var <%=object_name%> = {
$('#<%=dom_id(@recurring_todo)%>').slideUp(1000, function() { $('#<%=dom_id(@recurring_todo)%>').slideUp(1000, function() {
$('#<%=dom_id(@recurring_todo)%>').remove(); $('#<%=dom_id(@recurring_todo)%>').remove();
<%=object_name%>.show_empty_messages(); <%=object_name%>.show_empty_messages();
<%- if @recurring_todo.completed? -%> <%- if @recurring_todo.completed? -%>
<%=object_name%>.add_recurring_todo_to_completed_container(); <%=object_name%>.add_recurring_todo_to_completed_container();
<%- else -%> <%- else -%>
@ -48,4 +48,4 @@ var <%=object_name%> = {
} }
<%=object_name%>.animate(); <%=object_name%>.animate();
<%- end -%> <%- end -%>

View file

@ -3,6 +3,6 @@
<a href="https://github.com/TracksApp/tracks/wiki"><%= t('common.wiki')%></a> | <a href="https://github.com/TracksApp/tracks/wiki"><%= t('common.wiki')%></a> |
<a href="http://groups.google.com/group/TracksApp"><%= t('common.mailing_list')%></a> | <a href="http://groups.google.com/group/TracksApp"><%= t('common.mailing_list')%></a> |
<a href="http://getontracks.org/"><%= t('common.website')%></a> | <a href="http://getontracks.org/"><%= t('common.website')%></a> |
<a href="http://getontracks.org/development/"><%= t('common.contribute')%></a> | <a href="http://getontracks.org/development/"><%= t('common.contribute')%></a> |
<%= link_to(t('layouts.navigation.mobile'), todos_path(:format => 'm')) %></p> <%= link_to(t('layouts.navigation.mobile'), todos_path(:format => 'm')) %></p>
</div> </div>

View file

@ -1,5 +1,5 @@
<%- <%-
url = url_for :controller => 'stats', :action => 'actions_done_last_years' url = url_for :controller => 'stats', :action => 'actions_done_last_years'
-%> -%>
&title=<%= t('stats.actions_lastyear_title') %>,{font-size:16},& &title=<%= t('stats.actions_lastyear_title') %>,{font-size:16},&
&y_legend=<%= t('stats.legend.number_of_actions') %>,12,0x736AFF& &y_legend=<%= t('stats.legend.number_of_actions') %>,12,0x736AFF&

View file

@ -4,20 +4,20 @@
&y_ticks=5,10,5& &y_ticks=5,10,5&
&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8& &filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8&
&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8&
&values=<% &values=<%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=@actions_creation_hour_array[i] -%>, <%=@actions_creation_hour_array[i] -%>,
<% end -%><%=@actions_creation_hour_array[23]%>& <% end -%><%=@actions_creation_hour_array[23]%>&
&values_2=<% &values_2=<%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=@actions_completion_hour_array[i] -%>, <%=@actions_completion_hour_array[i] -%>,
<% end -%><%=@actions_completion_hour_array[23]%>& <% end -%><%=@actions_completion_hour_array[23]%>&
&x_labels= <% &x_labels= <%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=i-%>, <%=i-%>,
<% end -%>23& <% end -%>23&
&y_min=0& &y_min=0&
<% # add one to @max for people who have no actions completed yet. <% # add one to @max for people who have no actions completed yet.
# OpenFlashChart cannot handle y_max=0 -%> # OpenFlashChart cannot handle y_max=0 -%>
&y_max=<%=@max+1 -%>& &y_max=<%=@max+1 -%>&
&x_label_style=9,,1,1& &x_label_style=9,,1,1&

View file

@ -4,20 +4,20 @@
&y_ticks=5,10,5& &y_ticks=5,10,5&
&filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8& &filled_bar=50,0x9933CC,0x8010A0,<%= t('stats.labels.created') %>,8&
&filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8& &filled_bar_2=50,0x0066CC,0x0066CC,<%= t('stats.labels.completed') %>,8&
&values=<% &values=<%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=@actions_creation_hour_array[i] -%>, <%=@actions_creation_hour_array[i] -%>,
<% end -%><%=@actions_creation_hour_array[23]%>& <% end -%><%=@actions_creation_hour_array[23]%>&
&values_2=<% &values_2=<%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=@actions_completion_hour_array[i] -%>, <%=@actions_completion_hour_array[i] -%>,
<% end -%><%=@actions_completion_hour_array[23]%>& <% end -%><%=@actions_completion_hour_array[23]%>&
&x_labels= <% &x_labels= <%
0.upto 22 do |i| -%> 0.upto 22 do |i| -%>
<%=i-%>, <%=i-%>,
<% end -%>23& <% end -%>23&
&y_min=0& &y_min=0&
<% # add one to @max for people who have no actions completed yet. <% # add one to @max for people who have no actions completed yet.
# OpenFlashChart cannot handle y_max=0 -%> # OpenFlashChart cannot handle y_max=0 -%>
&y_max=<%=@max+1 -%>& &y_max=<%=@max+1 -%>&
&x_label_style=9,,1,1& &x_label_style=9,,1,1&

View file

@ -10,7 +10,7 @@
<%= render :partial => "todos/todo", :collection => @done_recently, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> <%= render :partial => "todos/todo", :collection => @done_recently, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %>
<% end -%> <% end -%>
</div> </div>
<div class="container"> <div class="container">
<div class=add_note_link><%= link_to t('common.show_all'), done_projects_path%></div> <div class=add_note_link><%= link_to t('common.show_all'), done_projects_path%></div>
<h2> <h2>
@ -39,5 +39,5 @@
<%= render :partial => @last_completed_recurring_todos %> <%= render :partial => @last_completed_recurring_todos %>
<% end -%> <% end -%>
</div> </div>
</div> </div>

View file

@ -1,8 +1,8 @@
<%= <%=
settings[:show_container] = !collection.empty? || settings[:show_empty_containers] settings[:show_container] = !collection.empty? || settings[:show_empty_containers]
todos_container(settings) do todos_container(settings) do
todos_container_header(settings) + todos_container_header(settings) +
todos_container_items(collection, settings) todos_container_items(collection, settings)
end end
%> %>

View file

@ -1,8 +1,8 @@
<%= <%=
settings[:show_container] = !collection.empty? || settings[:show_empty_containers] settings[:show_container] = !collection.empty? || settings[:show_empty_containers]
todos_container(settings) do todos_container(settings) do
todos_container_header(settings) + todos_container_header(settings) +
todos_container_items(collection, settings) todos_container_items(collection, settings)
end end
%> %>

View file

@ -7,9 +7,9 @@ cache [successor, "successor"] do
<div id="<%= dom_id(successor, 'successor_line') %>"> <div id="<%= dom_id(successor, 'successor_line') %>">
<div class="description<%= staleness_class( successor ) %>" style="margin-left: 20px"> <div class="description<%= staleness_class( successor ) %>" style="margin-left: 20px">
<span class="todo.descr"><%= h sanitize(successor.description) %></span> <span class="todo.descr"><%= h sanitize(successor.description) %></span>
<%= remote_delete_dependency(successor, predecessor) %> <%= remote_delete_dependency(successor, predecessor) %>
<% unless successor.pending_successors.empty? <% unless successor.pending_successors.empty?
if @rec_depth < 8 if @rec_depth < 8
@rec_depth+=1 %> @rec_depth+=1 %>
@ -29,4 +29,4 @@ cache [successor, "successor"] do
</div> </div>
</div> </div>
</div> </div>
<% end %> <% end %>

View file

@ -1,5 +1,5 @@
animate: function() { animate: function() {
<%- <%-
animation = [] animation = []
animation << "remove_todo" if update_needs_to_remove_todo_from_container animation << "remove_todo" if update_needs_to_remove_todo_from_container
if replace_with_updated_todo if replace_with_updated_todo
@ -106,10 +106,10 @@ regenerate_predecessor_family: function() {
parents = @todo.predecessors.to_a parents = @todo.predecessors.to_a
until parents.empty? until parents.empty?
parent = parents.pop parent = parents.pop
parents += parent.predecessors parents += parent.predecessors
-%> -%>
$('#<%= dom_id(parent) %>').html("<%= escape_javascript(render(:partial => parent, :locals => { :settings => {:parent_container_type => parent_container_type }})) %>"); $('#<%= dom_id(parent) %>').html("<%= escape_javascript(render(:partial => parent, :locals => { :settings => {:parent_container_type => parent_container_type }})) %>");
<% <%
end end
-%> -%>
} }

View file

@ -18,7 +18,7 @@
<%= render :partial => "todos/todo", :collection => @done, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> <%= render :partial => "todos/todo", :collection => @done, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %>
<% end -%> <% end -%>
</div> </div>
<div class="paginate_footer"><%= will_paginate @done, paginate_options %></div> <div class="paginate_footer"><%= will_paginate @done, paginate_options %></div>
</div> </div>

View file

@ -8,7 +8,7 @@
animation = [] animation = []
if should_show_new_item if should_show_new_item
if should_add_new_container if should_add_new_container
animation << "insert_new_container_with_new_todo"; animation << "insert_new_container_with_new_todo";
else else
animation << "add_todo_to_existing_container"; animation << "add_todo_to_existing_container";
@ -41,13 +41,13 @@
empty_id = '#no_todos_in_view' empty_id = '#no_todos_in_view'
empty_id = '#deferred_pending_container-empty-d' if source_view_is :tickler empty_id = '#deferred_pending_container-empty-d' if source_view_is :tickler
-%> -%>
$('<%=empty_id%>').slideUp(100, function() { $('<%=empty_id%>').slideUp(100, function() {
$('#display_box').prepend(html_for_new_container()); $('#display_box').prepend(html_for_new_container());
next_steps.go(); next_steps.go();
}); });
} }
function add_todo_to_existing_container(next_steps) { function add_todo_to_existing_container(next_steps) {
$('#<%= empty_container_msg_div_id %>').hide(); $('#<%= empty_container_msg_div_id %>').hide();
$('#<%= item_container_id(@todo) %>_items').append(html_for_new_todo()); $('#<%= item_container_id(@todo) %>_items').append(html_for_new_todo());
$('#<%= item_container_id(@todo) %>').slideDown(500, function() { $('#<%= item_container_id(@todo) %>').slideDown(500, function() {
@ -71,7 +71,7 @@
} }
function html_for_new_container() { function html_for_new_container() {
<% <%
want_render = @group_view_by == 'project' ? @new_project_created : @new_context_created want_render = @group_view_by == 'project' ? @new_project_created : @new_context_created
container = @group_view_by == 'project' ? @todo.project : @todo.context container = @group_view_by == 'project' ? @todo.project : @todo.context
%> %>
@ -81,5 +81,5 @@
function html_for_new_todo() { function html_for_new_todo() {
return "<%= @saved ? js_render(@todo, { :parent_container_type => parent_container_type, :source_view => @source_view }) : "" %>"; return "<%= @saved ? js_render(@todo, { :parent_container_type => parent_container_type, :source_view => @source_view }) : "" %>";
} }
<% end -%> <% end -%>

View file

@ -5,8 +5,8 @@
<%= show_completed_todos_for("rest_of_month", @done_rest_of_month) %> <%= show_completed_todos_for("rest_of_month", @done_rest_of_month) %>
<p> <p>
<%= raw t('todos.see_all_completed', <%= raw t('todos.see_all_completed',
:link => link_to(t("todos.all_completed_here"), determine_all_done_path)) :link => link_to(t("todos.all_completed_here"), determine_all_done_path))
%> %>
</p> </p>

View file

@ -1,10 +1,10 @@
<%- object_name = unique_object_name_for("edit_todo_#{@todo.id}") %> <%- object_name = unique_object_name_for("edit_todo_#{@todo.id}") %>
function add_spec(id, spec) { function add_spec(id, spec) {
<%- <%-
# do this outside of object_name to fill spec_of_todo in # do this outside of object_name to fill spec_of_todo in
# global namespace, not in namespace of object. Otherwise # global namespace, not in namespace of object. Otherwise
# spec_of_todo is not available for the js attached to the # spec_of_todo is not available for the js attached to the
# edit form # edit form
-%> -%>
spec_of_todo[id] = spec; spec_of_todo[id] = spec;
@ -37,4 +37,4 @@ var <%=object_name%> = {
} }
} }
<%=object_name%>.animate(); <%=object_name%>.animate();

View file

@ -1,8 +1,8 @@
<% <%
options = { options = {
:collapsible => false, :collapsible => false,
:parent_container_type => 'tag', :parent_container_type => 'tag',
:title_param => @tag_title :title_param => @tag_title
} }
deferred_pending_options=options.clone.merge({:deferred => @deferred_todos, :pending => @pending_todos}) deferred_pending_options=options.clone.merge({:deferred => @deferred_todos, :pending => @pending_todos})
hidden_options = options.clone hidden_options = options.clone
@ -28,4 +28,4 @@
<div id="input_box"> <div id="input_box">
<%= render :partial => "shared/add_new_item_form" %> <%= render :partial => "shared/add_new_item_form" %>
<%= render :file => "sidebar/sidebar" %> <%= render :file => "sidebar/sidebar" %>
</div> </div>

View file

@ -1,11 +1,11 @@
<% unless @saved -%> <% unless @saved -%>
TracksPages.page_error("<%= t('todos.error_toggle_complete') %>"); TracksPages.page_error("<%= t('todos.error_toggle_complete') %>");
<% else <% else
# create a unique object name to prevent concurrent toggles to overwrite each other functions # create a unique object name to prevent concurrent toggles to overwrite each other functions
object_name = unique_object_name_for("toggle_check") object_name = unique_object_name_for("toggle_check")
-%> -%>
var <%= object_name %> = { var <%= object_name %> = {
animate: function() { animate: function() {
<% if @wants_redirect_after_complete && @todo.completed? -%> <% if @wants_redirect_after_complete && @todo.completed? -%>
<%=object_name%>.redirect_after_complete(); <%=object_name%>.redirect_after_complete();
<% else <% else
@ -182,4 +182,4 @@ var <%= object_name %> = {
} }
<%=object_name%>.animate(); <%=object_name%>.animate();
<% end -%> <% end -%>

View file

@ -1,5 +1,5 @@
<div id="single_box" class="container context authtype_container"> <div id="single_box" class="container context authtype_container">
<h2><%= t('users.change_authentication_type') %></h2> <h2><%= t('users.change_authentication_type') %></h2>
<%= get_list_of_error_messages_for @user %> <%= get_list_of_error_messages_for @user %>
@ -7,12 +7,12 @@
<p><%= t('users.select_authentication_type') %></p> <p><%= t('users.select_authentication_type') %></p>
<%= form_tag :action => 'update_auth_type' do %> <%= form_tag :action => 'update_auth_type' do %>
<div><label for="user_auth_type"><%= t('users.label_auth_type') %>:</label> <%= select('user', 'auth_type', Tracks::Config.auth_schemes.collect {|p| [ p, p ] }) %></div> <div><label for="user_auth_type"><%= t('users.label_auth_type') %>:</label> <%= select('user', 'auth_type', Tracks::Config.auth_schemes.collect {|p| [ p, p ] }) %></div>
<div id="open_id" style="display:<%= current_user.auth_type == 'open_id' ? 'block' : 'none' %>"><label for="openid_url"><%= t('users.identity_url') %>:</label> <input type="text" name="openid_url" value="<%= current_user.open_id_url %>" class="open_id" /></div> <div id="open_id" style="display:<%= current_user.auth_type == 'open_id' ? 'block' : 'none' %>"><label for="openid_url"><%= t('users.identity_url') %>:</label> <input type="text" name="openid_url" value="<%= current_user.open_id_url %>" class="open_id" /></div>
<div class="actions"><%= submit_tag t('users.auth_change_submit') %> <%= link_to t('common.cancel'), preferences_path %></div> <div class="actions"><%= submit_tag t('users.auth_change_submit') %> <%= link_to t('common.cancel'), preferences_path %></div>
<%= observe_field( :user_auth_type, :function => "$('#open_id')[0].style.display = value == 'open_id' ? 'block' : 'none'") %>
<%= observe_field( :user_auth_type, :function => "$('#open_id')[0].style.display = value == 'open_id' ? 'block' : 'none'") %>
<% end %> <% end %>
</div> </div>

View file

@ -2,8 +2,8 @@
<p><%= t('users.total_users_count', :count => "<span id=\"user_count\">#{@total_users}</span>").html_safe %></p> <p><%= t('users.total_users_count', :count => "<span id=\"user_count\">#{@total_users}</span>").html_safe %></p>
<table class="users_table"> <table class="users_table">
<tr> <tr>
<th><%= User.human_attribute_name('login') %></th> <th><%= User.human_attribute_name('login') %></th>
<th><%= User.human_attribute_name('display_name') %></th> <th><%= User.human_attribute_name('display_name') %></th>
<th><%= User.human_attribute_name('auth_type') %></th> <th><%= User.human_attribute_name('auth_type') %></th>
@ -13,7 +13,7 @@
<th><%= t('users.total_projects') %></th> <th><%= t('users.total_projects') %></th>
<th><%= t('users.total_notes') %></th> <th><%= t('users.total_notes') %></th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
<% for user in @users %> <% for user in @users %>
<tr <%= "class=\"highlight\"" if user.is_admin? %> id="user-<%= user.id %>"> <tr <%= "class=\"highlight\"" if user.is_admin? %> id="user-<%= user.id %>">
<td><%=h user.login %></td> <td><%=h user.login %></td>

View file

@ -4,7 +4,7 @@
<%= get_list_of_error_messages_for @user %><br/> <%= get_list_of_error_messages_for @user %><br/>
<%= render_flash %> <%= render_flash %>
<h3><%= @heading -%></h3> <h3><%= @heading -%></h3>
<table> <table>
@ -12,14 +12,14 @@
<td><label for="user_login"><%= t('users.desired_login') %>:</label></td> <td><label for="user_login"><%= t('users.desired_login') %>:</label></td>
<td> <%= text_field "user", "login", :size => 20 %></td> <td> <%= text_field "user", "login", :size => 20 %></td>
</tr> </tr>
<tr> <tr>
<td><label for="user_password"><%= t('users.choose_password') %>:</label></td> <td><label for="user_password"><%= t('users.choose_password') %>:</label></td>
<td><%= password_field "user", "password", :size => 20 %></td> <td><%= password_field "user", "password", :size => 20 %></td>
</tr> </tr>
<tr> <tr>
<td><label for="user_password_confirmation"><%= t('users.confirm_password') %>:</label></td> <td><label for="user_password_confirmation"><%= t('users.confirm_password') %>:</label></td>
<td><%= password_field "user", "password_confirmation", :size => 20 %></td> <td><%= password_field "user", "password_confirmation", :size => 20 %></td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
<td><input type="submit" id="signup" value="<%= t('users.signup') %> &#187;" class="primary" /></td> <td><input type="submit" id="signup" value="<%= t('users.signup') %> &#187;" class="primary" /></td>

View file

@ -1,5 +1,5 @@
<div title="No signups" id="signupform" class="form"> <div title="No signups" id="signupform" class="form">
<h3>No Signups</h3> <h3>No Signups</h3>
<p>You don't have permission to sign up for a new account.</p> <p>You don't have permission to sign up for a new account.</p>
<p>Please contact the site administrator <%= mail_to "#{@admin_email}", "by email", :encode => "hex" %> to get permission.</p> <p>Please contact the site administrator <%= mail_to "#{@admin_email}", "by email", :encode => "hex" %> to get permission.</p>
</div> </div>