diff --git a/.gitignore b/.gitignore index 8e2cc0f5..708770e1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ config/database.yml config/site.yml config/deploy.rb db/*.sqlite3 +db/*.db db/data.yml db/schema.rb log diff --git a/Gemfile.lock b/Gemfile.lock index 5807ec3c..22ef61ba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,35 +3,35 @@ GEM specs: RedCloth (4.2.9) aasm (3.0.8) - actionmailer (3.2.6) - actionpack (= 3.2.6) + actionmailer (3.2.8) + actionpack (= 3.2.8) mail (~> 2.4.4) - actionpack (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) + actionpack (3.2.8) + activemodel (= 3.2.8) + activesupport (= 3.2.8) builder (~> 3.0.0) erubis (~> 2.7.0) - journey (~> 1.0.1) + journey (~> 1.0.4) rack (~> 1.4.0) rack-cache (~> 1.2) rack-test (~> 0.6.1) sprockets (~> 2.1.3) - activemodel (3.2.6) - activesupport (= 3.2.6) + activemodel (3.2.8) + activesupport (= 3.2.8) builder (~> 3.0.0) - activerecord (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) + activerecord (3.2.8) + activemodel (= 3.2.8) + activesupport (= 3.2.8) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.6) - activemodel (= 3.2.6) - activesupport (= 3.2.6) - activesupport (3.2.6) + activeresource (3.2.8) + activemodel (= 3.2.8) + activesupport (= 3.2.8) + activesupport (3.2.8) i18n (~> 0.6) multi_json (~> 1.0) - acts_as_list (0.1.6) - addressable (2.2.8) + acts_as_list (0.1.8) + addressable (2.3.2) arel (3.0.2) aruba (0.4.11) childprocess (>= 0.2.3) @@ -48,8 +48,8 @@ GEM rack-test (>= 0.5.4) selenium-webdriver (~> 2.0) xpath (~> 0.1.4) - childprocess (0.3.3) - ffi (~> 1.0.6) + childprocess (0.3.5) + ffi (~> 1.0, >= 1.0.6) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) @@ -72,12 +72,12 @@ GEM erubis (2.7.0) execjs (1.4.0) multi_json (~> 1.0) - factory_girl (3.5.0) + factory_girl (4.0.0) activesupport (>= 3.0.0) - factory_girl_rails (3.5.0) - factory_girl (~> 3.5.0) + factory_girl_rails (4.0.0) + factory_girl (~> 4.0.0) railties (>= 3.0.0) - ffi (1.0.11) + ffi (1.1.5) formatize (1.1.0) RedCloth (~> 4.2) actionpack (~> 3.0) @@ -92,9 +92,9 @@ GEM jquery-rails (2.0.2) railties (>= 3.2.0, < 5.0) thor (~> 0.14) - json (1.7.3) + json (1.7.4) libv8 (3.3.10.4) - libwebsocket (0.1.4) + libwebsocket (0.1.5) addressable mail (2.4.4) i18n (>= 0.4.0) @@ -115,19 +115,19 @@ GEM rack rack-test (0.6.1) rack (>= 1.0) - rails (3.2.6) - actionmailer (= 3.2.6) - actionpack (= 3.2.6) - activerecord (= 3.2.6) - activeresource (= 3.2.6) - activesupport (= 3.2.6) + rails (3.2.8) + actionmailer (= 3.2.8) + actionpack (= 3.2.8) + activerecord (= 3.2.8) + activeresource (= 3.2.8) + activesupport (= 3.2.8) bundler (~> 1.0) - railties (= 3.2.6) + railties (= 3.2.8) rails_autolink (1.0.9) rails (~> 3.1) - railties (3.2.6) - actionpack (= 3.2.6) - activesupport (= 3.2.6) + railties (3.2.8) + actionpack (= 3.2.8) + activesupport (= 3.2.8) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) @@ -139,8 +139,8 @@ GEM rspec-core (~> 2.11.0) rspec-expectations (~> 2.11.0) rspec-mocks (~> 2.11.0) - rspec-core (2.11.0) - rspec-expectations (2.11.1) + rspec-core (2.11.1) + rspec-expectations (2.11.2) diff-lcs (~> 1.1.3) rspec-mocks (2.11.1) rubyzip (0.9.9) @@ -151,7 +151,7 @@ GEM railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - selenium-webdriver (2.24.0) + selenium-webdriver (2.25.0) childprocess (>= 0.2.5) libwebsocket (~> 0.1.3) multi_json (~> 1.0) @@ -161,21 +161,21 @@ GEM rack (~> 1.0) tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.6) - swf_fu (2.0.2) + swf_fu (2.0.3) coffee-script rails (>= 3.1) - therubyracer (0.10.1) + therubyracer (0.10.2) libv8 (~> 3.3.10) thor (0.15.4) tilt (1.3.3) - tolk (1.3.1) + tolk (1.3.2) will_paginate ya2yaml (~> 0.26) treetop (1.4.10) polyglot polyglot (>= 0.3.1) tzinfo (0.3.33) - uglifier (1.2.6) + uglifier (1.2.7) execjs (>= 0.3.0) multi_json (~> 1.3) will_paginate (3.0.3) diff --git a/README b/README.md similarity index 94% rename from README rename to README.md index 848cefa0..942b298a 100644 --- a/README +++ b/README.md @@ -1,5 +1,7 @@ # Tracks: a GTD(TM) web application, built with Ruby on Rails +[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/TracksApp/tracks) + * Project homepage: http://getontracks.org/ * Manual: http://getontracks.org/manual/ * Source at GitHub: http://github.com/TracksApp/tracks/ @@ -37,4 +39,4 @@ 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! \ No newline at end of file +Enjoy being productive! diff --git a/app/assets/javascripts/tracks.js b/app/assets/javascripts/tracks.js index 7f34644a..148db688 100644 --- a/app/assets/javascripts/tracks.js +++ b/app/assets/javascripts/tracks.js @@ -252,6 +252,7 @@ var TracksPages = { ContextItems.setup_autocomplete_for_contexts('input[name=context_name]'); ContextItems.setup_autocomplete_for_contexts('input[id="project_default_context_name"]'); TracksPages.setup_autocomplete_for_tag_list('input[name=tag_list]'); // todo edit form + TracksPages.setup_autocomplete_for_tag_list('input[name=edit_recurring_todo_tag_list]'); TracksPages.setup_autocomplete_for_tag_list('input[id="project_default_tags"]'); TodoItems.setup_autocomplete_for_predecessor(); }, diff --git a/app/assets/stylesheets/tracks.css b/app/assets/stylesheets/tracks.css index e2c4a38b..e2eda344 100644 --- a/app/assets/stylesheets/tracks.css +++ b/app/assets/stylesheets/tracks.css @@ -1430,3 +1430,14 @@ div.auto_complete ul strong.highlight { .ui-autocomplete-loading { background: white url('/assets/ui-anim_basic_16x16.gif') right center no-repeat; } + +ul.todo-submenu > li > a { + position: relative; + padding-left: 24px; +} + +ul.todo-submenu > li > a > img { + position: absolute; + left: 0px; + top: 0px; +} diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index 81b9d952..715188ff 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -3,7 +3,6 @@ class ContextsController < ApplicationController helper :todos before_filter :init, :except => [:index, :create, :destroy, :order] - before_filter :init_todos, :only => :show before_filter :set_context_from_params, :only => [:update, :destroy] skip_before_filter :login_required, :only => [:index] prepend_before_filter :login_or_feed_token_required, :only => [:index] @@ -40,6 +39,21 @@ class ContextsController < ApplicationController end def show + set_context_from_params + + unless @context.nil? + @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) + @not_done_todos = @context.todos.active.reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(Todo::DEFAULT_INCLUDES) + + @deferred = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES) + @pending = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES) + + @projects = current_user.projects + + @count = @not_done_todos.count + @deferred.count + @pending.count + end + @contexts = current_user.contexts(true) if @context.nil? respond_to do |format| @@ -250,28 +264,4 @@ class ContextsController < ApplicationController init_data_for_sidebar end - def init_todos - set_context_from_params - unless @context.nil? - @max_completed = current_user.prefs.show_number_completed - @done = @context.todos.completed.all(:limit => @max_completed) - - # @not_done_todos = @context.not_done_todos TODO: Temporarily doing this - # search manually until I can work out a way to do the same thing using - # not_done_todos acts_as_todo_container method Hides actions in hidden - # projects from context. - @not_done_todos = @context.todos.active( - :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", - :include => Todo::DEFAULT_INCLUDES) - - @deferred = @context.todos.deferred(:include => Todo::DEFAULT_INCLUDES) - @pending = @context.todos.pending(:include => Todo::DEFAULT_INCLUDES) - - @projects = current_user.projects - - @count = @not_done_todos.count + @deferred.count + @pending.count - end - - end - end diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index 3f3c7f65..d6ac9f1d 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -510,13 +510,7 @@ class TodosController < ApplicationController format.xml { render :xml => @todo.to_xml( *to_xml_params ) } format.m do if @saved - if cookies[:mobile_url] - old_path = cookies[:mobile_url] - cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} - redirect_to old_path - else - redirect_to todos_path(:format => 'm') - end + do_mobile_todo_redirection else render :action => "edit", :format => :m end @@ -798,14 +792,8 @@ class TodosController < ApplicationController format.html { redirect_to :back } format.js {render :action => 'update'} format.m { - notify(:notice, t("todos.action_deferred", :description => @todo.description)) - if cookies[:mobile_url] - old_path = cookies[:mobile_url] - cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} - redirect_to old_path - else - redirect_to todos_path(:format => 'm') - end + notify(:notice, t("todos.action_deferred", :description => @todo.description)) + do_mobile_todo_redirection } end end @@ -900,13 +888,10 @@ class TodosController < ApplicationController end def convert_to_project - @todo = current_user.todos.find_by_id(params[:id]) - @project = current_user.projects.new(:name => @todo.description, :description => @todo.notes, - :default_context => @todo.context) - - unless @project.invalid? - @todo.destroy - @project.save! + todo = current_user.todos.find_by_id(params[:id]) + @project = Project.create_from_todo(todo) + + if @project.valid? redirect_to project_url(@project) else flash[:error] = "Could not create project from todo: #{@project.errors.full_messages[0]}" @@ -929,6 +914,16 @@ class TodosController < ApplicationController private + def do_mobile_todo_redirection + if cookies[:mobile_url] + old_path = cookies[:mobile_url] + cookies[:mobile_url] = {:value => nil, :secure => SITE_CONFIG['secure_cookies']} + redirect_to old_path + else + redirect_to todos_path(:format => 'm') + end + end + def to_xml_params if params[:limit_fields] == 'index' return [:only => [:id, :created_at, :updated_at, :completed_at] ] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 40a7e01f..fc2d432e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -205,7 +205,7 @@ module ApplicationHelper }.each do |s| js << "i18n['#{s}'] = '#{ t(s).gsub(/'/, "\\\\'") }';\n" end - return js + return js.html_safe end def javascript_tag_for_i18n_datepicker diff --git a/app/models/project.rb b/app/models/project.rb index 32681008..e5e6205e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -47,6 +47,21 @@ class Project < ActiveRecord::Base NullProject.new end + def self.create_from_todo(todo) + project = Project.new(:name => todo.description, + :description => todo.notes, + :default_context => todo.context) + + project.user = todo.user + + if project.valid? + todo.destroy + project.save! + end + + project + end + def hide_todos todos.each do |t| unless t.completed? || t.deferred? diff --git a/app/views/todos/_todo.html.erb b/app/views/todos/_todo.html.erb index a6167584..ee744c38 100644 --- a/app/views/todos/_todo.html.erb +++ b/app/views/todos/_todo.html.erb @@ -14,7 +14,7 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' <%= remote_edit_button(todo) unless suppress_edit_button %>