diff --git a/.gitignore b/.gitignore index bd1d8742..433e85a0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ nbproject vendor/plugins/query_trace/ db/schema.rb .dotest +public/javascripts/cache +public/stylesheets/cache \ No newline at end of file diff --git a/README b/README index 28cf4e46..5cce7ac7 100644 --- a/README +++ b/README @@ -8,12 +8,10 @@ * Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss * Original developer: bsag (http://www.rousette.org.uk/) * Contributors: http://dev.rousette.org.uk/wiki/Tracks/Contributing/Contributors -* Version: 1.6 +* Version: 1.7RC * Copyright: (cc) 2004-2008 rousette.org.uk. * License: GNU GPL -**An important note for version 1.6: OpenID support is broken in this release. The fix isn't trivial because of changes to the `ruby-openid` gem, so we wanted to get this version out now and fix OpenID for the next release. If you depend on OpenID integration, we recommend waiting until the next release.** - All the documentation for Tracks can be found within the /doc directory. It contains a manual in HTML (manual.html) or PDF format (manual.pdf), and this includes full instructions for both new installations and upgrades from older installations of Tracks. The instructions might appear long and intimidatingly complex, but that is mostly because of the number of different platforms supported, and the different configurations which can be used (e.g. running Tracks on your local computer or on a remote server). If you choose the appropriate section for your situation (installation vs. upgrade), and use the easiest (recommended) method, you should find the instructions easy to follow. If you encounter problems, try searching the wiki, forum or mailing list (URLs above), and ask a question if you cannot find a solution to your problem. For those upgrading, change notes are available in /doc/CHANGELOG. If you are thinking about contributing towards the development of Tracks, please read /doc/README_DEVELOPERS for general information, or /doc/tracks_api_wrapper.rb for information on Tracks' API. @@ -21,3 +19,4 @@ For those upgrading, change notes are available in /doc/CHANGELOG. If you are th While fully usable for everyday use, Tracks is still a work in progress. Make sure that you take sensible precautions and back up all your data frequently, taking particular care when you are upgrading. Enjoy being productive! + diff --git a/app/controllers/application.rb b/app/controllers/application.rb index b24dfd54..0d54b75f 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -32,13 +32,13 @@ class ApplicationController < ActionController::Base before_filter :set_time_zone prepend_before_filter :login_required prepend_before_filter :enable_mobile_content_negotiation - after_filter :restore_content_type_for_mobile after_filter :set_charset include ActionView::Helpers::TextHelper include ActionView::Helpers::SanitizeHelper + extend ActionView::Helpers::SanitizeHelper::ClassMethods helper_method :format_date, :markdown # By default, sets the charset to UTF-8 if it isn't already set @@ -148,21 +148,15 @@ class ApplicationController < ActionController::Base # during the processing and then setting it to 'text/html' in an # 'after_filter' -LKM 2007-04-01 def mobile? - return params[:format] == 'm' || response.content_type == MOBILE_CONTENT_TYPE + return params[:format] == 'm' end def enable_mobile_content_negotiation if mobile? - request.accepts.unshift(Mime::Type::lookup(MOBILE_CONTENT_TYPE)) + request.format = :m end end - def restore_content_type_for_mobile - if mobile? - response.content_type = 'text/html' - end - end - def create_todo_from_recurring_todo(rt, date=nil) # create todo and initialize with data from recurring_todo rt todo = current_user.todos.build( { :description => rt.description, :notes => rt.notes, :project_id => rt.project_id, :context_id => rt.context_id}) @@ -234,8 +228,13 @@ class ApplicationController < ActionController::Base end def init_data_for_sidebar - @projects = @projects || current_user.projects.find(:all, :include => [:default_context ]) - @contexts = @contexts || current_user.contexts + @completed_projects = current_user.projects.completed + @hidden_projects = current_user.projects.hidden + @active_projects = current_user.projects.active + + @active_contexts = current_user.contexts.active + @hidden_contexts = current_user.contexts.hidden + init_not_done_counts if prefs.show_hidden_projects_in_sidebar init_project_hidden_todo_counts(['project']) @@ -244,13 +243,13 @@ class ApplicationController < ActionController::Base def init_not_done_counts(parents = ['project','context']) parents.each do |parent| - eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || Todo.count(:conditions => ['user_id = ? and state = ?', current_user.id, 'active'], :group => :#{parent}_id)") + eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || current_user.todos.active.count(:group => :#{parent}_id)") end end def init_project_hidden_todo_counts(parents = ['project','context']) parents.each do |parent| - eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || Todo.count(:conditions => ['user_id = ? and (state = ? or state = ?)', current_user.id, 'project_hidden', 'active'], :group => :#{parent}_id)") + eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || current_user.todos.count(:conditions => ['state = ? or state = ?', 'project_hidden', 'active'], :group => :#{parent}_id)") end end diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index 34c11d26..348151aa 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -134,8 +134,8 @@ class ContextsController < ApplicationController def render_contexts_mobile lambda do @page_title = "TRACKS::List Contexts" - @active_contexts = @contexts.find(:all, { :conditions => ["hide = ?", false]}) - @hidden_contexts = @contexts.find(:all, { :conditions => ["hide = ?", true]}) + @active_contexts = @contexts.active + @hidden_contexts = @contexts.hidden @down_count = @active_contexts.size + @hidden_contexts.size cookies[:mobile_url]= {:value => request.request_uri, :secure => TRACKS_COOKIES_SECURE} render :action => 'index_mobile' @@ -201,6 +201,9 @@ class ContextsController < ApplicationController :conditions => ['todos.state = ? AND (todos.project_id IS ? OR projects.state = ?)', 'active', nil, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [:project, :tags]) + + @projects = current_user.projects + @count = @not_done_todos.size @default_project_context_name_map = build_default_project_context_name_map(@projects).to_json end diff --git a/app/controllers/feedlist_controller.rb b/app/controllers/feedlist_controller.rb index 68c7118c..4c2924e9 100644 --- a/app/controllers/feedlist_controller.rb +++ b/app/controllers/feedlist_controller.rb @@ -12,12 +12,12 @@ class FeedlistController < ApplicationController @contexts = current_user.contexts end - @active_projects = @projects.select{ |p| p.active? } - @hidden_projects = @projects.select{ |p| p.hidden? } - @completed_projects = @projects.select{ |p| p.completed? } + @active_projects = current_user.projects.active + @hidden_projects = current_user.projects.hidden + @completed_projects = current_user.projects.completed - @active_contexts = @contexts.select{ |c| !c.hidden? } - @hidden_contexts = @contexts.select{ |c| c.hidden? } + @active_contexts = current_user.contexts.active + @hidden_contexts = current_user.contexts.hidden respond_to do |format| format.html { render :layout => 'standard' } diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb index 1b071c1e..26f5f99d 100644 --- a/app/controllers/integrations_controller.rb +++ b/app/controllers/integrations_controller.rb @@ -1,5 +1,7 @@ class IntegrationsController < ApplicationController + skip_before_filter :login_required, :only => :search_plugin + def index @page_title = 'TRACKS::Integrations' end @@ -22,4 +24,12 @@ class IntegrationsController < ApplicationController context = current_user.contexts.find params[:context_id] render :partial => 'applescript2', :locals => { :context => context } end + + def search_plugin + @icon_data = [File.open(RAILS_ROOT + '/public/images/done.png').read]. + pack('m').gsub(/\n/, '') + + render :layout => false + end + end diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index a9b7e8be..91cfc261 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -6,114 +6,45 @@ class LoginController < ApplicationController skip_before_filter :login_required before_filter :login_optional before_filter :get_current_user - open_id_consumer if openid_enabled? def login - @page_title = "TRACKS::Login" - @openid_url = cookies[:openid_url] if openid_enabled? - case request.method - when :post - if @user = User.authenticate(params['user_login'], params['user_password']) - session['user_id'] = @user.id - # If checkbox on login page checked, we don't expire the session after 1 hour - # of inactivity and we remember this user for future browser sessions - session['noexpiry'] = params['user_noexpiry'] - msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire." - notify :notice, "Login successful: session #{msg}" - cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE } - unless should_expire_sessions? - @user.remember_me - cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE } + if openid_enabled? && using_open_id? + login_openid + else + @page_title = "TRACKS::Login" + case request.method + when :post + if @user = User.authenticate(params['user_login'], params['user_password']) + session['user_id'] = @user.id + # If checkbox on login page checked, we don't expire the session after 1 hour + # of inactivity and we remember this user for future browser sessions + session['noexpiry'] = params['user_noexpiry'] + msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire." + notify :notice, "Login successful: session #{msg}" + cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE } + unless should_expire_sessions? + @user.remember_me + cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE } + end + redirect_back_or_home + return + else + @login = params['user_login'] + notify :warning, "Login unsuccessful" end - redirect_back_or_home - return - else - @login = params['user_login'] - notify :warning, "Login unsuccessful" - end - when :get - if User.no_users_yet? - redirect_to :controller => 'users', :action => 'new' - return - end - end - respond_to do |format| - format.html - format.m { render :action => 'login_mobile.html.erb', :layout => 'mobile' } + when :get + if User.no_users_yet? + redirect_to :controller => 'users', :action => 'new' + return + end + end + respond_to do |format| + format.html + format.m { render :action => 'login_mobile.html.erb', :layout => 'mobile' } + end end end - def begin - # If the URL was unusable (either because of network conditions, - # a server error, or that the response returned was not an OpenID - # identity page), the library will return HTTP_FAILURE or PARSE_ERROR. - # Let the user know that the URL is unusable. - case open_id_response.status - when OpenID::SUCCESS - session['openid_url'] = params[:openid_url] - session['user_noexpiry'] = params[:user_noexpiry] - # The URL was a valid identity URL. Now we just need to send a redirect - # to the server using the redirect_url the library created for us. - - # redirect to the server - respond_to do |format| - format.html { redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), open_id_complete_url) } - format.m { redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), formatted_open_id_complete_url(:format => 'm')) } - end - else - notify :warning, "Unable to find openid server for #{openid_url}" - redirect_to_login - end - end - - def complete - openid_url = session['openid_url'] - if openid_url.blank? - notify :error, "expected an openid_url" - end - - case open_id_response.status - when OpenID::FAILURE - # In the case of failure, if info is non-nil, it is the - # URL that we were verifying. We include it in the error - # message to help the user figure out what happened. - if open_id_response.identity_url - msg = "Verification of #{openid_url}(#{open_id_response.identity_url}) failed. " - else - msg = "Verification failed. " - end - notify :error, open_id_response.msg.to_s + msg - - when OpenID::SUCCESS - # Success means that the transaction completed without - # error. If info is nil, it means that the user cancelled - # the verification. - @user = User.find_by_open_id_url(openid_url) - unless (@user.nil?) - session['user_id'] = @user.id - session['noexpiry'] = session['user_noexpiry'] - msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire." - notify :notice, "You have successfully verified #{openid_url} as your identity. Login successful: session #{msg}" - cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE } - unless should_expire_sessions? - @user.remember_me - cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE } - end - cookies[:openid_url] = { :value => openid_url, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE } - redirect_back_or_home - else - notify :warning, "You have successfully verified #{openid_url} as your identity, but you do not have a Tracks account. Please ask your administrator to sign you up." - end - - when OpenID::CANCEL - notify :warning, "Verification cancelled." - - else - notify :warning, "Unknown response status: #{open_id_response.status}" - end - redirect_to_login unless performed? - end - def logout @user.forget_me if logged_in? cookies.delete :auth_token @@ -156,5 +87,31 @@ class LoginController < ApplicationController def should_expire_sessions? session['noexpiry'] != "on" end - + + protected + + def login_openid + # If checkbox on login page checked, we don't expire the session after 1 hour + # of inactivity and we remember this user for future browser sessions + session['noexpiry'] ||= params['user_noexpiry'] + authenticate_with_open_id do |result, identity_url| + if result.successful? + if @user = User.find_by_open_id_url(identity_url) + session['user_id'] = @user.id + msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire." + notify :notice, "Login successful: session #{msg}" + cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE } + unless should_expire_sessions? + @user.remember_me + cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE } + end + redirect_back_or_home + else + notify :warning, "Sorry, no user by that identity URL exists (#{identity_url})" + end + else + notify :warning, result.message + end + end + end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index b2489c7d..9443168f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -31,7 +31,7 @@ class ProjectsController < ApplicationController end def projects_and_actions - @projects = @projects.select { |p| p.active? } + @projects = @projects.active respond_to do |format| format.text { render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT @@ -83,7 +83,7 @@ class ProjectsController < ApplicationController @go_to_project = params['go_to_project'] @saved = @project.save @project_not_done_counts = { @project.id => 0 } - @active_projects_count = current_user.projects.count(:conditions => "state = 'active'") + @active_projects_count = current_user.projects.active.count @contexts = current_user.contexts respond_to do |format| format.js { @down_count = current_user.projects.size } @@ -124,9 +124,9 @@ class ProjectsController < ApplicationController @project_not_done_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true) end @contexts = current_user.contexts - @active_projects_count = current_user.projects.count(:conditions => "state = 'active'") - @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'") - @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'") + @active_projects_count = current_user.projects.active.count + @hidden_projects_count = current_user.projects.hidden.count + @completed_projects_count = current_user.projects.completed.count render :template => 'projects/update.js.rjs' return elsif boolean_param('update_status') @@ -161,9 +161,9 @@ class ProjectsController < ApplicationController def destroy @project.destroy - @active_projects_count = current_user.projects.count(:conditions => "state = 'active'") - @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'") - @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'") + @active_projects_count = current_user.projects.active.count + @hidden_projects_count = current_user.projects.hidden.count + @completed_projects_count = current_user.projects.completed.count respond_to do |format| format.js { @down_count = current_user.projects.size } format.xml { render :text => "Deleted project #{@project.name}" } @@ -199,9 +199,9 @@ class ProjectsController < ApplicationController lambda do @page_title = "TRACKS::List Projects" @count = current_user.projects.size - @active_projects = @projects.select{ |p| p.active? } - @hidden_projects = @projects.select{ |p| p.hidden? } - @completed_projects = @projects.select{ |p| p.completed? } + @active_projects = @projects.active + @hidden_projects = @projects.hidden + @completed_projects = @projects.completed @no_projects = @projects.empty? @projects.cache_note_counts @new_project = current_user.projects.build @@ -211,9 +211,9 @@ class ProjectsController < ApplicationController def render_projects_mobile lambda do - @active_projects = @projects.select{ |p| p.active? } - @hidden_projects = @projects.select{ |p| p.hidden? } - @completed_projects = @projects.select{ |p| p.completed? } + @active_projects = @projects.active + @hidden_projects = @projects.hidden + @completed_projects = @projects.completed @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size cookies[:mobile_url]= {:value => request.request_uri, :secure => TRACKS_COOKIES_SECURE} render :action => 'index_mobile' diff --git a/app/controllers/recurring_todos_controller.rb b/app/controllers/recurring_todos_controller.rb index 9928a4d5..668e6acb 100644 --- a/app/controllers/recurring_todos_controller.rb +++ b/app/controllers/recurring_todos_controller.rb @@ -118,7 +118,7 @@ class RecurringTodosController < ApplicationController else @message += " / did not create todo" end - @count = current_user.recurring_todos.count(:all, :conditions => ["state = ?", "active"]) + @count = current_user.recurring_todos.active.count else @message = "Error saving recurring todo" end @@ -140,7 +140,7 @@ class RecurringTodosController < ApplicationController # delete the recurring todo @saved = @recurring_todo.destroy - @remaining = current_user.recurring_todos.count(:all) + @remaining = current_user.recurring_todos.count respond_to do |format| diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index baaa25dd..93bdb23e 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,27 +1,30 @@ -class SearchController < ApplicationController - - helper :todos, :application, :notes, :projects - - def results - @source_view = params['_source_view'] || 'search' - @page_title = "TRACKS::Search Results for #{params[:search]}" - terms = '%' + params[:search] + '%' - @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context]) - @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? or description LIKE ?", terms, terms]) - @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms]) - - @count = @found_todos.size + @found_projects.size + @found_notes.size - - init_not_done_counts(['project']) - init_project_hidden_todo_counts(['project']) - end - - def index - @page_title = "TRACKS::Search" - end - - def init - @source_view = params['_source_view'] || 'search' - end - -end +class SearchController < ApplicationController + + helper :todos, :application, :notes, :projects + + def results + @source_view = params['_source_view'] || 'search' + @page_title = "TRACKS::Search Results for #{params[:search]}" + terms = '%' + params[:search] + '%' + @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context]) + @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? OR description LIKE ?", terms, terms]) + @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms]) + @found_contexts = current_user.contexts.find(:all, :conditions => ["name LIKE ?", terms]) + # TODO: limit search to tags on todos + @found_tags = current_user.tags.find(:all, :conditions => ["name LIKE ?", terms]) + + @count = @found_todos.size + @found_projects.size + @found_notes.size + @found_contexts.size + @found_tags.size + + init_not_done_counts + init_project_hidden_todo_counts + end + + def index + @page_title = "TRACKS::Search" + end + + def init + @source_view = params['_source_view'] || 'search' + end + +end diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index c74811d4..2d0f95c6 100755 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -8,7 +8,7 @@ class StatsController < ApplicationController @page_title = 'TRACKS::Statistics' @unique_tags = @tags.count(:all, {:group=>"tag_id"}) - @hidden_contexts = @contexts.find(:all, {:conditions => ["hide = ? ", true]}) + @hidden_contexts = @contexts.hidden @first_action = @actions.find(:first, :order => "created_at ASC") get_stats_actions diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index ad3a762a..8ccf710a 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -14,7 +14,7 @@ class TodosController < ApplicationController @projects = current_user.projects.find(:all, :include => [:default_context]) @contexts = current_user.contexts.find(:all) - @contexts_to_show = @contexts.reject {|x| x.hide? } + @contexts_to_show = current_user.contexts.active respond_to do |format| format.html &render_todos_html @@ -28,7 +28,7 @@ class TodosController < ApplicationController end def new - @projects = current_user.projects.select { |p| p.active? } + @projects = current_user.projects.active @contexts = current_user.contexts.find(:all) respond_to do |format| format.m { @@ -76,7 +76,7 @@ class TodosController < ApplicationController format.m do @return_path=cookies[:mobile_url] # todo: use function for this fixed path - @return_path='/mobile' if @return_path.nil? + @return_path='/m' if @return_path.nil? if @saved redirect_to @return_path else @@ -116,7 +116,7 @@ class TodosController < ApplicationController def show respond_to do |format| format.m do - @projects = current_user.projects.select { |p| p.active? } + @projects = current_user.projects.active @contexts = current_user.contexts.find(:all) @edit_mobile = true @return_path=cookies[:mobile_url] @@ -399,8 +399,9 @@ class TodosController < ApplicationController :limit => max_completed, :conditions => ['taggings.user_id = ? and state = ?', current_user.id, 'completed'], :order => 'todos.completed_at DESC') - - @contexts = current_user.contexts.find(:all) + + @projects = current_user.projects + @contexts = current_user.contexts @contexts_to_show = @contexts.reject {|x| x.hide? } # Set count badge to number of items with this tag @@ -442,33 +443,33 @@ class TodosController < ApplicationController due_next_week_date = due_this_week_date + 7.days due_this_month_date = Time.zone.now.end_of_month - @due_today = current_user.todos.find(:all, + @due_today = current_user.todos.not_completed.find(:all, :include => [:taggings, :tags], - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due <= ?', 'active', 'deferred', due_today_date], + :conditions => ['todos.due <= ?', due_today_date], :order => "due") - @due_this_week = current_user.todos.find(:all, + @due_this_week = current_user.todos.not_completed.find(:all, :include => [:taggings, :tags], - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_today_date, due_this_week_date], + :conditions => ['todos.due > ? AND todos.due <= ?', due_today_date, due_this_week_date], :order => "due") - @due_next_week = current_user.todos.find(:all, + @due_next_week = current_user.todos.not_completed.find(:all, :include => [:taggings, :tags], - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_this_week_date, due_next_week_date], + :conditions => ['todos.due > ? AND todos.due <= ?', due_this_week_date, due_next_week_date], :order => "due") - @due_this_month = current_user.todos.find(:all, + @due_this_month = current_user.todos.not_completed.find(:all, :include => [:taggings, :tags], - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_next_week_date, due_this_month_date], + :conditions => ['todos.due > ? AND todos.due <= ?', due_next_week_date, due_this_month_date], :order => "due") - @due_after_this_month = current_user.todos.find(:all, + @due_after_this_month = current_user.todos.not_completed.find(:all, :include => [:taggings, :tags], - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ?', 'active', 'deferred', due_this_month_date], + :conditions => ['todos.due > ?', due_this_month_date], :order => "due") - + + @count = current_user.todos.not_completed.are_due.count + respond_to do |format| format.html format.ics { - @due_all = current_user.todos.find(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND NOT todos.due IS NULL', 'active', 'deferred'], - :order => "due") + @due_all = current_user.todos.not_completed.are_due.find(:all, :order => "due") render :action => 'calendar', :layout => false, :content_type => Mime::ICS } end @@ -536,13 +537,17 @@ class TodosController < ApplicationController end def with_parent_resource_scope(&block) + @feed_title = "Actions " if (params[:context_id]) @context = current_user.contexts.find_by_params(params) + @feed_title = @feed_title + "in context '#{@context.name}'" Todo.send :with_scope, :find => {:conditions => ['todos.context_id = ?', @context.id]} do yield end elsif (params[:project_id]) @project = current_user.projects.find_by_params(params) + @feed_title = @feed_title + "in project '#{@project.name}'" + @project_feed = true Todo.send :with_scope, :find => {:conditions => ['todos.project_id = ?', @project.id]} do yield end @@ -718,7 +723,7 @@ class TodosController < ApplicationController render_rss_feed_for @todos, :feed => todo_feed_options, :item => { :title => :description, - :link => lambda { |t| context_url(t.context) }, + :link => lambda { |t| @project_feed.nil? ? context_url(t.context) : project_url(t.project) }, :guid => lambda { |t| todo_url(t) }, :description => todo_feed_content } @@ -726,7 +731,9 @@ class TodosController < ApplicationController end def todo_feed_options - Todo.feed_options(current_user) + options = Todo.feed_options(current_user) + options[:title] = @feed_title + return options end def todo_feed_content @@ -779,8 +786,8 @@ class TodosController < ApplicationController if todo.from_recurring_todo? recurring_todo = todo.recurring_todo - # check if there are active todos belonging to this recurring todo. - # only add new one if all active todos are completed + # check if there are active todos belonging to this recurring todo. only + # add new one if all active todos are completed if recurring_todo.todos.active.count == 0 # check for next todo either from the due date or the show_from date @@ -788,7 +795,7 @@ class TodosController < ApplicationController # if both due and show_from are nil, check for a next todo from now date_to_check = Time.zone.now if date_to_check.nil? - + if recurring_todo.active? && recurring_todo.has_next_todo(date_to_check) # shift the reference date to yesterday if date_to_check is furher in @@ -799,7 +806,7 @@ class TodosController < ApplicationController # that new todos due for today will be created instead of new todos # for tomorrow. date = date_to_check.at_midnight >= Time.zone.now.at_midnight ? date_to_check : Time.zone.now-1.day - + new_recurring_todo = create_todo_from_recurring_todo(recurring_todo, date) end end @@ -834,20 +841,20 @@ class TodosController < ApplicationController due_this_month_date = Time.zone.now.end_of_month case id when "due_today" - return 0 == current_user.todos.count(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due <= ?', 'active', 'deferred', due_today_date]) + return 0 == current_user.todos.not_completed.count(:all, + :conditions => ['todos.due <= ?', due_today_date]) when "due_this_week" - return 0 == current_user.todos.count(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_today_date, due_this_week_date]) + return 0 == current_user.todos.not_completed.count(:all, + :conditions => ['todos.due > ? AND todos.due <= ?', due_today_date, due_this_week_date]) when "due_next_week" - return 0 == current_user.todos.count(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_this_week_date, due_next_week_date]) + return 0 == current_user.todos.not_completed.count(:all, + :conditions => ['todos.due > ? AND todos.due <= ?', due_this_week_date, due_next_week_date]) when "due_this_month" - return 0 == current_user.todos.count(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_next_week_date, due_this_month_date]) + return 0 == current_user.todos.not_completed.count(:all, + :conditions => ['todos.due > ? AND todos.due <= ?', due_next_week_date, due_this_month_date]) when "due_after_this_month" - return 0 == current_user.todos.count(:all, - :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ?', 'active', 'deferred', due_this_month_date]) + return 0 == current_user.todos.not_completed.count(:all, + :conditions => ['todos.due > ?', due_this_month_date]) else raise Exception.new, "unknown due id for calendar: '#{id}'" end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 860f31cc..98f45cb9 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,10 +1,4 @@ class UsersController < ApplicationController - - if openid_enabled? - open_id_consumer - before_filter :begin_open_id_auth, :only => :update_auth_type - end - before_filter :admin_login_required, :only => [ :index, :show, :destroy ] skip_before_filter :login_required, :only => [ :new, :create ] prepend_before_filter :login_optional, :only => [ :new, :create ] @@ -153,18 +147,25 @@ class UsersController < ApplicationController end def update_auth_type - if (params[:user][:auth_type] == 'open_id') && openid_enabled? - case open_id_response.status - when OpenID::SUCCESS - # The URL was a valid identity URL. Now we just need to send a redirect - # to the server using the redirect_url the library created for us. - session['openid_url'] = params[:openid_url] - - # redirect to the server - redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), url_for(:action => 'complete')) + if (params[:open_id_complete] || (params[:user][:auth_type] == 'open_id')) && openid_enabled? + authenticate_with_open_id do |result, identity_url| + if result.successful? + # Success means that the transaction completed without + # error. If info is nil, it means that the user cancelled + # the verification. + @user.auth_type = 'open_id' + @user.open_id_url = identity_url + if @user.save + notify :notice, "You have successfully verified #{identity_url} as your identity and set your authentication type to Open ID." + else + debugger + notify :warning, "You have successfully verified #{identity_url} as your identity but there was a problem saving your authentication preferences." + end + redirect_to preferences_path else - notify :warning, "Unable to find openid server for #{openid_url}" + notify :warning, result.message redirect_to :action => 'change_auth_type' + end end return end @@ -178,47 +179,6 @@ class UsersController < ApplicationController end end - def complete - return unless openid_enabled? - openid_url = session['openid_url'] - if openid_url.blank? - notify :error, "expected an openid_url" - end - case open_id_response.status - when OpenID::FAILURE - # In the case of failure, if info is non-nil, it is the - # URL that we were verifying. We include it in the error - # message to help the user figure out what happened. - if open_id_response.identity_url - msg = "Verification of #{openid_url}(#{open_id_response.identity_url}) failed. " - else - msg = "Verification failed. " - end - notify :error, open_id_response.msg.to_s + msg - - when OpenID::SUCCESS - # Success means that the transaction completed without - # error. If info is nil, it means that the user cancelled - # the verification. - @user.auth_type = 'open_id' - @user.open_id_url = openid_url - if @user.save - notify :notice, "You have successfully verified #{openid_url} as your identity and set your authentication type to Open ID." - else - notify :warning, "You have successfully verified #{openid_url} as your identity but there was a problem saving your authentication preferences." - end - redirect_to preferences_path - - when OpenID::CANCEL - notify :warning, "Verification cancelled." - - else - notify :warning, "Unknown response status: #{open_id_response.status}" - end - redirect_to :action => 'change_auth_type' unless performed? - end - - def refresh_token @user.generate_token @user.save! diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a4147313..549f2fbc 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -8,7 +8,7 @@ module ApplicationHelper # Replicates the link_to method but also checks request.request_uri to find # current page. If that matches the url, the link is marked id = "current" - # + # def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference) if html_options html_options = html_options.stringify_keys @@ -29,7 +29,7 @@ module ApplicationHelper # Check due date in comparison to today's date Flag up date appropriately with # a 'traffic light' colour code - # + # def due_date(due) if due == nil return "" @@ -62,7 +62,7 @@ module ApplicationHelper # Check due date in comparison to today's date Flag up date appropriately with # a 'traffic light' colour code Modified method for mobile screen - # + # def due_date_mobile(due) if due == nil return "" @@ -92,7 +92,7 @@ module ApplicationHelper # 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 # actions or multiple actions - # + # def count_undone_todos_phrase(todos_parent, string="actions") @controller.count_undone_todos_phrase(todos_parent, string) end @@ -143,5 +143,31 @@ module ApplicationHelper page.replace 'flash', "

#{message}

" page.visual_effect :fade, 'flash', :duration => fade_duration end - + + def recurrence_time_span(rt) + case rt.ends_on + when "no_end_date" + return rt.start_from.nil? ? "" : "from " + format_date(rt.start_from) + when "ends_on_number_of_times" + return "for "+rt.number_of_occurences.to_s + " times" + when "ends_on_end_date" + starts = rt.start_from.nil? ? "" : "from " + format_date(rt.start_from) + ends = rt.end_date.nil? ? "" : " until " + format_date(rt.end_date) + return starts+ends + else + raise Exception.new, "unknown recurrence time span selection (#{rt.ends_on})" + end + end + + def recurrence_pattern_as_text(recurring_todo) + rt = recurring_todo.recurring_target_as_text + rp = recurring_todo.recurrence_pattern + # only add space if recurrence_pattern has content + rp = " " + rp if !rp.nil? + rts = recurrence_time_span(recurring_todo) + # only add space if recurrence_time_span has content + rts = " " + rts if !(rts == "") + return rt+rp+rts + end + end diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 42ebe65e..170c6aca 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -1,5 +1,5 @@ module NotesHelper def truncated_note(note, characters = 50) - sanitize(textilize_without_paragraph(truncate(note.body, characters, "..."))) + sanitize(textilize_without_paragraph(truncate(note.body, :length => characters, :omission => "..."))) end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ce2c0364..c0a6640d 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -20,12 +20,12 @@ module ProjectsHelper def project_next_prev html = '' unless @previous_project.nil? - project_name = truncate(@previous_project.name, 40, "...") + project_name = truncate(@previous_project.name, :length => 40, :omission => "...") html << link_to_project(@previous_project, "« #{project_name}") end html << ' | ' if @previous_project && @next_project unless @next_project.nil? - project_name = truncate(@next_project.name, 40, "...") + project_name = truncate(@next_project.name, :length => 40, :omission => "...") html << link_to_project(@next_project, "#{project_name} »") end html @@ -34,12 +34,12 @@ module ProjectsHelper def project_next_prev_mobile html = '' unless @previous_project.nil? - project_name = truncate(@previous_project.name, 40, "...") + project_name = truncate(@previous_project.name, :length => 40, :omission => "...") html << link_to_project_mobile(@previous_project, "5", "« 5-#{project_name}") end html << ' | ' if @previous_project && @next_project unless @next_project.nil? - project_name = truncate(@next_project.name, 40, "...") + project_name = truncate(@next_project.name, :length => 40, :omission => "...") html << link_to_project_mobile(@next_project, "6", "6-#{project_name} »") end html diff --git a/app/helpers/recurring_todos_helper.rb b/app/helpers/recurring_todos_helper.rb index b346e7ea..4ba1a690 100644 --- a/app/helpers/recurring_todos_helper.rb +++ b/app/helpers/recurring_todos_helper.rb @@ -1,37 +1,11 @@ module RecurringTodosHelper - - def recurrence_time_span(rt) - case rt.ends_on - when "no_end_date" - return "" - when "ends_on_number_of_times" - return "for "+rt.number_of_occurences.to_s + " times" - when "ends_on_end_date" - starts = rt.start_from.nil? ? "" : "from " + format_date(rt.start_from) - ends = rt.end_date.nil? ? "" : " until " + format_date(rt.end_date) - return starts+ends - else - raise Exception.new, "unknown recurrence time span selection (#{self.ends_on})" - end - end - - def recurrence_target(rt) - case rt.target - when 'due_date' - return "due" - when 'show_from_date' - return "show" - else - return "ERROR" - end - end def recurring_todo_tag_list tags_except_starred = @recurring_todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME} - tag_list = tags_except_starred.collect{|t| "" + + tag_list = tags_except_starred.collect{|t| "" + # link_to(t.name, :controller => "todos", :action => "tag", :id => # t.name) + TODO: tag view for recurring_todos (yet?) - t.name + + t.name + ""}.join('') "#{tag_list}" end @@ -44,7 +18,7 @@ module RecurringTodosHelper str end - def recurring_todo_remote_star_icon + def recurring_todo_remote_star_icon str = link_to( image_tag_for_star(@recurring_todo), toggle_star_recurring_todo_path(@recurring_todo), :class => "icon star_item", :title => "star the action '#{@recurring_todo.description}'") diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index aee59c90..0b38d202 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -117,7 +117,7 @@ module TodosHelper "" + link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) + ""}.join('') - "#{tag_list}" + if tag_list.empty? then "" else "#{tag_list}" end end def deferred_due_date @@ -242,13 +242,13 @@ module TodosHelper end def project_names_for_autocomplete - array_or_string_for_javascript( ['None'] + @projects.select{ |p| p.active? }.collect{|p| escape_javascript(p.name) } ) + array_or_string_for_javascript( ['None'] + current_user.projects.active.collect{|p| escape_javascript(p.name) } ) end def context_names_for_autocomplete # #return array_or_string_for_javascript(['Create a new context']) if # @contexts.empty? - array_or_string_for_javascript( @contexts.collect{|c| escape_javascript(c.name) } ) + array_or_string_for_javascript( current_user.contexts.collect{|c| escape_javascript(c.name) } ) end def format_ical_notes(notes) diff --git a/app/models/context.rb b/app/models/context.rb index 39cce497..41d27a53 100644 --- a/app/models/context.rb +++ b/app/models/context.rb @@ -2,7 +2,10 @@ class Context < ActiveRecord::Base has_many :todos, :dependent => :delete_all, :include => :project, :order => "todos.completed_at DESC" belongs_to :user - + + named_scope :active, :conditions => { :hide => false } + named_scope :hidden, :conditions => { :hide => true } + acts_as_list :scope => :user extend NamePartFinder include Tracks::TodoList diff --git a/app/models/message_gateway.rb b/app/models/message_gateway.rb index 8fcb78d3..501650e0 100644 --- a/app/models/message_gateway.rb +++ b/app/models/message_gateway.rb @@ -1,5 +1,7 @@ class MessageGateway < ActionMailer::Base include ActionView::Helpers::SanitizeHelper + extend ActionView::Helpers::SanitizeHelper::ClassMethods + def receive(email) user = User.find(:first, :include => [:preference], :conditions => ["preferences.sms_email = ?", email.from[0].strip]) if user.nil? diff --git a/app/models/project.rb b/app/models/project.rb index 396d49cc..4013e985 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -3,6 +3,10 @@ class Project < ActiveRecord::Base has_many :notes, :dependent => :delete_all, :order => "created_at DESC" belongs_to :default_context, :class_name => "Context", :foreign_key => "default_context_id" belongs_to :user + + named_scope :active, :conditions => { :state => 'active' } + named_scope :hidden, :conditions => { :state => 'hidden' } + named_scope :completed, :conditions => { :state => 'completed'} validates_presence_of :name, :message => "project must have a name" validates_length_of :name, :maximum => 255, :message => "project name must be less than 256 characters" diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb index 4561ed58..7d24b7eb 100644 --- a/app/models/recurring_todo.rb +++ b/app/models/recurring_todo.rb @@ -295,6 +295,17 @@ class RecurringTodo < ActiveRecord::Base def recurring_target=(t) self.target = t end + + def recurring_target_as_text + case self.target + when 'due_date' + return "due" + when 'show_from_date' + return "show" + else + raise Exception.new, "unexpected value of recurrence target '#{self.target}'" + end + end def recurring_show_days_before=(days) self.show_from_delta=days @@ -361,6 +372,8 @@ class RecurringTodo < ActiveRecord::Base when 'show_from' # so leave due date empty return nil + else + raise Exception.new, "unexpected value of recurrence target '#{self.target}'" end end @@ -471,12 +484,23 @@ class RecurringTodo < ActiveRecord::Base start = determine_start(previous) day = self.every_other1 n = self.every_other2 - + case self.recurrence_selector when 0 # specific day of the month - if start.mday >= day + if start.mday >= day # there is no next day n in this month, search in next month - start += n.months + # + # start += n.months + # + # The above seems to not work. Fiddle with timezone. Looks like we hit a + # bug in rails here where 2008-12-01 +0100 plus 1.month becomes + # 2008-12-31 +0100. For now, just calculate in UTC and convert back to + # local timezone. + # + # TODO: recheck if future rails versions have this problem too + start = Time.utc(start.year, start.month, start.day)+n.months + start = Time.zone.local(start.year, start.month, start.day) + # go back to day end return Time.zone.local(start.year, start.month, day) diff --git a/app/models/todo.rb b/app/models/todo.rb index f432037d..5aed02be 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -7,6 +7,7 @@ class Todo < ActiveRecord::Base named_scope :active, :conditions => { :state => 'active' } named_scope :not_completed, :conditions => ['NOT state = ? ', 'completed'] + named_scope :are_due, :conditions => ['NOT todos.due IS NULL'] STARRED_TAG_NAME = "starred" diff --git a/app/models/user.rb b/app/models/user.rb index 8a85b64b..6c0302cc 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -124,7 +124,7 @@ class User < ActiveRecord::Base #for will_paginate plugin cattr_accessor :per_page - @@per_page = 1 + @@per_page = 5 def validate unless Tracks::Config.auth_schemes.include?(auth_type) @@ -145,8 +145,8 @@ class User < ActiveRecord::Base return nil end - def self.find_by_open_id_url(raw_open_id_url) - normalized_open_id_url = normalize_open_id_url(raw_open_id_url) + def self.find_by_open_id_url(raw_identity_url) + normalized_open_id_url = OpenIdAuthentication.normalize_url(raw_identity_url) find(:first, :conditions => ['open_id_url = ?', normalized_open_id_url]) end @@ -188,7 +188,7 @@ class User < ActiveRecord::Base end def at_midnight(date) - return TimeZone[prefs.time_zone].local(date.year, date.month, date.day, 0, 0, 0) + return ActiveSupport::TimeZone[prefs.time_zone].local(date.year, date.month, date.day, 0, 0, 0) end def generate_token @@ -237,13 +237,6 @@ protected def normalize_open_id_url return if open_id_url.nil? - self.open_id_url = self.class.normalize_open_id_url(open_id_url) + self.open_id_url = OpenIdAuthentication.normalize_url(open_id_url) end - - def self.normalize_open_id_url(raw_open_id_url) - normalized = raw_open_id_url - normalized = "http://#{raw_open_id_url}" unless raw_open_id_url =~ /\:\/\// - normalized.downcase.chomp('/') - end - end diff --git a/app/views/contexts/_context_listing.rhtml b/app/views/contexts/_context_listing.rhtml index 03ad73f3..32335457 100644 --- a/app/views/contexts/_context_listing.rhtml +++ b/app/views/contexts/_context_listing.rhtml @@ -1,9 +1,14 @@ -<% context = context_listing %> +<% context = context_listing + suppress_drag_handle ||= false + suppress_edit_button ||= false +%>
" class="list">
-
- DRAG -
+ <% unless suppress_drag_handle -%> +
+ DRAG +
+ <% end -%>
<%= link_to_context( context ) %> <%= " (" + count_undone_todos_phrase(context,"actions") + ")" %>
@@ -32,5 +37,5 @@ -%>
- <%= render :partial => 'context_form', :object => context %> + <%= render :partial => 'contexts/context_form', :object => context %> \ No newline at end of file diff --git a/app/views/contexts/_mobile_context.rhtml b/app/views/contexts/_mobile_context.rhtml index 6510aeb4..52236e1f 100644 --- a/app/views/contexts/_mobile_context.rhtml +++ b/app/views/contexts/_mobile_context.rhtml @@ -6,9 +6,9 @@ if not @not_done.empty? # only show a context when there are actions in it -%>

<%=mobile_context.name%>

- +
-<% end -%> \ No newline at end of file + +<% end -%> diff --git a/app/views/contexts/show.html.erb b/app/views/contexts/show.html.erb index eded894d..a22e4728 100644 --- a/app/views/contexts/show.html.erb +++ b/app/views/contexts/show.html.erb @@ -8,5 +8,5 @@
<%= render :partial => "shared/add_new_item_form" %> -<%= render "sidebar/sidebar" %> + <%= render :template => "sidebar/sidebar" %>
\ No newline at end of file diff --git a/app/views/feedlist/index.html.erb b/app/views/feedlist/index.html.erb index 7acc405c..5c855e16 100644 --- a/app/views/feedlist/index.html.erb +++ b/app/views/feedlist/index.html.erb @@ -123,7 +123,7 @@
- <%= render "sidebar/sidebar" %> + <%= render :template => "sidebar/sidebar" %>
\ No newline at end of file diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index 0c7781e3..696cd0cf 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -74,5 +74,5 @@
<%= render :partial => "shared/add_new_item_form" %> - <%= render "sidebar/sidebar" %> + <%= render :template => "sidebar/sidebar" %>
diff --git a/app/views/recurring_todos/_recurring_todo.html.erb b/app/views/recurring_todos/_recurring_todo.html.erb index 3962b27b..a1d2c737 100644 --- a/app/views/recurring_todos/_recurring_todo.html.erb +++ b/app/views/recurring_todos/_recurring_todo.html.erb @@ -6,7 +6,7 @@
<%= sanitize(recurring_todo.description) %> <%= recurring_todo_tag_list %> - [<%=recurrence_target(recurring_todo)%> <%= recurring_todo.recurrence_pattern %> <%= recurrence_time_span(recurring_todo) %>] + [<%= recurrence_pattern_as_text(@recurring_todo) %>]
diff --git a/app/views/recurring_todos/create.js.rjs b/app/views/recurring_todos/create.js.rjs index 32602607..1704cf02 100644 --- a/app/views/recurring_todos/create.js.rjs +++ b/app/views/recurring_todos/create.js.rjs @@ -13,7 +13,7 @@ if @recurring_saved page.hide 'recurring-todos-empty-nd' page.insert_html :bottom, 'recurring_todos_container', - :partial => 'recurring_todos/recurring_todo' + :partial => 'recurring_todos/recurring_todo', :locals => { :recurring_todo => @recurring_todo} page.visual_effect :highlight, dom_id(@recurring_todo), :duration => 3 # update badge count page['badge_count'].replace_html @count diff --git a/app/views/recurring_todos/toggle_check.js.rjs b/app/views/recurring_todos/toggle_check.js.rjs index aa21b8c9..b0cde7ff 100644 --- a/app/views/recurring_todos/toggle_check.js.rjs +++ b/app/views/recurring_todos/toggle_check.js.rjs @@ -4,7 +4,7 @@ if @saved if @recurring_todo.completed? # show completed recurring todo - page.insert_html :top, "completed_recurring_todos_container", :partial => 'recurring_todos/recurring_todo' + page.insert_html :top, "completed_recurring_todos_container", :partial => 'recurring_todos/recurring_todo', :locals => { :recurring_todo => @recurring_todo } page.visual_effect :highlight, dom_id(@recurring_todo), :duration => 3 # set empty messages @@ -14,7 +14,7 @@ if @saved # recurring_todo is activated # show completed recurring todo - page.insert_html :top, "recurring_todos_container", :partial => 'recurring_todos/recurring_todo' + page.insert_html :top, "recurring_todos_container", :partial => 'recurring_todos/recurring_todo', :locals => { :recurring_todo => @recurring_todo } page.visual_effect :highlight, dom_id(@recurring_todo), :duration => 3 # inform user if a new todo has been created because of the activation diff --git a/app/views/recurring_todos/update.js.rjs b/app/views/recurring_todos/update.js.rjs index c8061a9c..ad35f1ef 100644 --- a/app/views/recurring_todos/update.js.rjs +++ b/app/views/recurring_todos/update.js.rjs @@ -13,7 +13,7 @@ if @saved page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}; projectAutoCompleter.changed = true" if @new_project_created # replace old recurring todo with updated todo - page.replace dom_id(@recurring_todo), :partial => 'recurring_todos/recurring_todo' + page.replace dom_id(@recurring_todo), :partial => 'recurring_todos/recurring_todo', :locals => { :recurring_todo => @recurring_todo } page.visual_effect :highlight, dom_id(@recurring_todo), :duration => 3 else diff --git a/app/views/search/index.rhtml b/app/views/search/index.rhtml index 7065746b..8cfcbd76 100644 --- a/app/views/search/index.rhtml +++ b/app/views/search/index.rhtml @@ -1,6 +1,9 @@ - + + \ No newline at end of file diff --git a/app/views/search/results.rhtml b/app/views/search/results.rhtml index 679360c5..e18516ee 100644 --- a/app/views/search/results.rhtml +++ b/app/views/search/results.rhtml @@ -1,32 +1,48 @@ -
- <% if @count == 0 -%> -

Your search yielded no results.

- <% else -%> - <% source_view_is = :search %> - <% parent_container_type = 'search' %> - <% if not @found_todos.empty? -%> -
-

<%= @found_todos.size %>Todos matching query

- <%= render :partial => "todos/todo", :collection => @found_todos, :locals => { :parent_container_type => 'search', :suppress_context => false, :suppress_project => false, :suppress_edit_button => true } %> -
- <% end -%> - - <% if not @found_projects.empty? -%> -
-

<%= @found_projects.size %>Projects matching query

- <%= render :partial => "projects/project_listing", :collection => @found_projects, :locals => { :suppress_drag_handle => true, :suppress_edit_button => true } %> -
- <% end -%> - - <% if not @found_notes.empty? -%> -
-

<%= @found_notes.size %>Notes matching query

- <% for notes in @found_notes -%> -
- <%= render :partial => "notes/notes_summary", :object => notes %> -
- <% end -%> -
- <% end -%> - <% end -%> -
+
+<% if @count == 0 -%> +

Your search yielded no results.

+<% else -%> + <% unless @found_todos.empty? -%> +
+

<%= @found_todos.size %>Todos matching query

+ <%= render :partial => "todos/todo", :collection => @found_todos, :locals => { :parent_container_type => 'search', :suppress_context => false, :suppress_project => false, :suppress_edit_button => true } %> +
+ <% end -%> + + <% unless @found_projects.empty? -%> +
+

<%= @found_projects.size %>Projects matching query

+ <%= render :partial => "projects/project_listing", :collection => @found_projects, :locals => { :suppress_drag_handle => true, :suppress_edit_button => true } %> +
+ <% end -%> + + <% unless @found_notes.empty? -%> +
+

<%= @found_notes.size %>Notes matching query

+ <% for notes in @found_notes -%> +
+ <%= render :partial => "notes/notes_summary", :object => notes %> +
+ <% end -%> +
+ <% end -%> + + <% unless @found_contexts.empty? -%> +
+

<%= @found_contexts.size %>Contexts matching query

+ <%= render :partial => "contexts/context_listing", :collection => @found_contexts, :locals => { :suppress_drag_handle => true, :suppress_edit_button => true } %> +
+ <% end -%> + + <% unless @found_tags.empty? -%> +
+

<%= @found_tags.size %>Tags matching query

+ <% @found_tags.each do |tag| -%> + <%= link_to tag.name, {:controller => "todos", :action => "tag", :id => tag.name} -%> + <% end %> + +
+
+ <% end %> +<% end -%> +
diff --git a/app/views/shared/_add_new_item_form.rhtml b/app/views/shared/_add_new_item_form.rhtml index 65316245..c84e0580 100644 --- a/app/views/shared/_add_new_item_form.rhtml +++ b/app/views/shared/_add_new_item_form.rhtml @@ -2,7 +2,7 @@ @todo = nil @initial_context_name = @context.name unless @context.nil? @initial_context_name ||= @project.default_context.name unless @project.nil? || @project.default_context.nil? - @initial_context_name ||= @contexts[0].name unless @contexts[0].nil? + @initial_context_name ||= current_user.contexts.first.name unless current_user.contexts.first.nil? @initial_project_name = @project.name unless @project.nil? %>
diff --git a/app/views/sidebar/sidebar.html.erb b/app/views/sidebar/sidebar.html.erb index bb5d8847..3de85ff3 100644 --- a/app/views/sidebar/sidebar.html.erb +++ b/app/views/sidebar/sidebar.html.erb @@ -1,30 +1,30 @@