diff --git a/.gitignore b/.gitignore index 34fd4e71..b2629579 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ config/database.yml config/environment.rb log -tmp \ No newline at end of file +tmp +db/data.yml \ No newline at end of file diff --git a/README b/README index 7ed8b4a5..3e6d8f9d 100644 --- a/README +++ b/README @@ -1,7 +1,6 @@ # Tracks: a GTD(TM) web application, built with Ruby on Rails * Project homepage: http://www.rousette.org.uk/projects/ -* Development page: http://tracks.lighthouseapp.com/projects/11609-tracks/overview * GitHub: http://github.com/bsag/tracks/ * Trac (for bug reports and feature requests): http://dev.rousette.org.uk/report/6 * Wiki (community contributed information): http://www.rousette.org.uk/projects/wiki/ @@ -9,10 +8,12 @@ * 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.5 -* Copyright: (cc) 2004-2006 rousette.org.uk. +* Version: 1.6 +* 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. diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index c44f592e..c28490ca 100755 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -481,8 +481,10 @@ class StatsController < ApplicationController @chart_name = "actions_visible_running_time_data" @page_title = "Actions selected from week " + @further = false if params['id'] == 'avrt_end' @page_title += week_from.to_s + " and further" + @further = true else @page_title += week_from.to_s + " - " + week_to.to_s + "" end @@ -512,8 +514,10 @@ class StatsController < ApplicationController @chart_name = "actions_running_time_data" @page_title = "Actions selected from week " + @further = false if params['id'] == 'art_end' @page_title += week_from.to_s + " and further" + @further = true else @page_title += week_from.to_s + " - " + week_to.to_s + "" end diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index a334e189..27f9d23d 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -154,6 +154,7 @@ class TodosController < ApplicationController end def update + @source_view = params['_source_view'] || 'todo' init_data_for_sidebar unless mobile? @todo.tag_with(params[:tag_list], current_user) if params[:tag_list] @original_item_context_id = @todo.context_id @@ -461,7 +462,11 @@ class TodosController < ApplicationController @todos = Todo.find(:all, :conditions => ['todos.user_id = ?', current_user.id], :include => [ :project, :context, :tags ]) # Exclude hidden projects from the home page - @not_done_todos = Todo.find(:all, :conditions => ['todos.user_id = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', current_user.id, false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) + @not_done_todos = Todo.find(:all, + :conditions => ['todos.user_id = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', + current_user.id, false, 'active'], + :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", + :include => [ :project, :context, :tags ]) end end @@ -475,8 +480,8 @@ class TodosController < ApplicationController # Exclude hidden projects from the home page @not_done_todos = Todo.find(:all, - :conditions => ['todos.user_id = ? AND todos.state = ? AND contexts.hide = ?', - current_user.id, 'active', false], + :conditions => ['todos.user_id = ? AND todos.state = ? AND contexts.hide = ? AND (projects.state = ? OR todos.project_id IS NULL)', + current_user.id, 'active', false, 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context ]) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9d750597..bd5fe39e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -116,7 +116,7 @@ class UsersController < ApplicationController # DELETE /users/somelogin # DELETE /users/somelogin.xml def destroy - @deleted_user = User.find_by_id(params[:id]) + @deleted_user = User.find_by_login(params[:id]) @saved = @deleted_user.destroy @total_users = User.find(:all).size diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 869f82e1..c543bbb0 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -22,55 +22,71 @@ module TodosHelper :prevent_default => true end - def remote_delete_icon + def set_behavior_for_delete_icon parameters = "_source_view=#{@source_view}" parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' - str = link_to( image_tag_for_delete, - todo_path(@todo), :id => "delete_icon_"+@todo.id.to_s, - :class => "icon delete_icon", :title => "delete the action '#{@todo.description}'") apply_behavior '.item-container a.delete_icon:click', :prevent_default => true do |page| page.confirming "'Are you sure that you want to ' + this.title + '?'" do page << "itemContainer = this.up('.item-container'); itemContainer.startWaiting();" page << remote_to_href(:method => 'delete', :with => "'#{parameters}'", :complete => "itemContainer.stopWaiting();") - end + end end + end + + def remote_delete_icon + str = link_to( image_tag_for_delete, + todo_path(@todo), :id => "delete_icon_"+@todo.id.to_s, + :class => "icon delete_icon", :title => "delete the action '#{@todo.description}'") + set_behavior_for_delete_icon str end + def set_behavior_for_star_icon + apply_behavior '.item-container a.star_item:click', + remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"), + :prevent_default => true + end + def remote_star_icon str = link_to( image_tag_for_star(@todo), toggle_star_todo_path(@todo), :class => "icon star_item", :title => "star the action '#{@todo.description}'") - apply_behavior '.item-container a.star_item:click', - remote_to_href(:method => 'put', :with => "{ _source_view : '#{@source_view}' }"), - :prevent_default => true + set_behavior_for_star_icon str end - def remote_edit_icon + def set_behavior_for_edit_icon parameters = "_source_view=#{@source_view}" parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' + apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page| + page << "Effect.Pulsate(this);" + page << remote_to_href(:method => 'get', :with => "'#{parameters}'") + end + end + + def remote_edit_icon if !@todo.completed? str = link_to( image_tag_for_edit, edit_todo_path(@todo), :class => "icon edit_icon") - apply_behavior '.item-container a.edit_icon:click', :prevent_default => true do |page| - page << "Effect.Pulsate(this);" - page << remote_to_href(:method => 'get', :with => "'#{parameters}'") - end + set_behavior_for_edit_icon else str = '' + image_tag("blank.png") + " " end str end - def remote_toggle_checkbox - str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox') + def set_behavior_for_toggle_checkbox parameters = "_source_view=#{@source_view}" parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag' apply_behavior '.item-container input.item-checkbox:click', remote_function(:url => javascript_variable('this.value'), :method => 'put', - :with => "'#{parameters}'") + :with => "'#{parameters}'") + end + + def remote_toggle_checkbox + str = check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox') + set_behavior_for_toggle_checkbox str end @@ -120,10 +136,10 @@ module TodosHelper str += @todo.project.name unless should_suppress_project str = "(#{str})" unless str.blank? else - if (['project', 'tag', 'stats', 'search'].include?(parent_container_type)) + if (['project', 'tag', 'stats', 'search'].include?(parent_container_type)) str << item_link_to_context( @todo ) end - if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id + if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id str << item_link_to_project( @todo ) end end @@ -265,4 +281,4 @@ module TodosHelper image_tag("blank.png", :title =>"Star action", :class => class_str) end -end +end \ No newline at end of file diff --git a/app/views/contexts/_context.rhtml b/app/views/contexts/_context.rhtml index 59809d23..7fb2e942 100644 --- a/app/views/contexts/_context.rhtml +++ b/app/views/contexts/_context.rhtml @@ -4,18 +4,21 @@ <% if collapsible -%> <%= image_tag("collapse.png") %> <% apply_behavior '.container_toggle:click', :prevent_default => true do |page| - page << "containerElem = this.up('.container') - toggleTarget = containerElem.down('.toggle_target') - if (Element.visible(toggleTarget)) - { - todoItems.collapseNextActionListing(this, toggleTarget); - todoItems.contextCollapseCookieManager.setCookie(todoItems.buildCookieName(containerElem), true) - } - else - { - todoItems.expandNextActionListing(this, toggleTarget); - todoItems.contextCollapseCookieManager.clearCookie(todoItems.buildCookieName(containerElem)) - } + page << " /* only handle the click if a previous click had finished its animation */ + if (todoItems.lastEffect == null || todoItems.lastEffect.state=='finished') { + containerElem = this.up('.container') + toggleTarget = containerElem.down('.toggle_target') + if (Element.visible(toggleTarget)) + { + todoItems.collapseNextActionListing(this, toggleTarget); + todoItems.contextCollapseCookieManager.setCookie(todoItems.buildCookieName(containerElem), true) + } + else + { + todoItems.expandNextActionListing(this, toggleTarget); + todoItems.contextCollapseCookieManager.clearCookie(todoItems.buildCookieName(containerElem)) + } + } " end %> @@ -31,6 +34,14 @@

Currently there are no incomplete actions in this context

-<%= render :partial => "todos/todo", :collection => @not_done, :locals => { :parent_container_type => "context" } %> + <%= render :partial => "todos/todo", :collection => @not_done, :locals => { :parent_container_type => "context" } %> + <% if @not_done.empty? + # fix (hack) for #713 + set_behavior_for_delete_icon + set_behavior_for_star_icon + set_behavior_for_edit_icon + set_behavior_for_toggle_checkbox + end + -%> diff --git a/app/views/contexts/_mobile_context.rhtml b/app/views/contexts/_mobile_context.rhtml index f6a2a268..6510aeb4 100644 --- a/app/views/contexts/_mobile_context.rhtml +++ b/app/views/contexts/_mobile_context.rhtml @@ -4,11 +4,11 @@ if not @not_done.empty? # only show a context when there are actions in it - %> -

<%=mobile_context.name%>

- - <%= render :partial => "todos/mobile_todo", - :collection => @not_done, - :locals => { :parent_container_type => "context" }%> -
+ -%> +

<%=mobile_context.name%>

+ +<%= render :partial => "todos/mobile_todo", + :collection => @not_done, + :locals => { :parent_container_type => "context" }-%> +
<% end -%> \ No newline at end of file diff --git a/app/views/contexts/_mobile_context_listing.rhtml b/app/views/contexts/_mobile_context_listing.rhtml index 6d792961..4f770186 100644 --- a/app/views/contexts/_mobile_context_listing.rhtml +++ b/app/views/contexts/_mobile_context_listing.rhtml @@ -1,2 +1,2 @@ -<% context = mobile_context_listing %> -
<%= link_to context.name, formatted_context_path(context, :m) %><%= " (" + count_undone_todos_phrase(context,"actions") + ")" %>
+<% context = mobile_context_listing -%> +
<%= link_to context.name, formatted_context_path(context, :m) %><%= " (" + count_undone_todos_phrase(context,"actions") + ")" %>
\ No newline at end of file diff --git a/app/views/contexts/index_mobile.rhtml b/app/views/contexts/index_mobile.rhtml index 35a1de9a..1edd16ed 100644 --- a/app/views/contexts/index_mobile.rhtml +++ b/app/views/contexts/index_mobile.rhtml @@ -1,6 +1,2 @@ -

Visible Contexts

-<%= render :partial => 'mobile_context_listing', :collection => @active_contexts%> - -

Hidden Contexts

-<%= render :partial => 'mobile_context_listing', :collection => @hidden_contexts %> - +

Visible Contexts

<%= render :partial => 'mobile_context_listing', :collection => @active_contexts %> +

Hidden Contexts

<%= render :partial => 'mobile_context_listing', :collection => @hidden_contexts %> \ No newline at end of file diff --git a/app/views/data/index.html.erb b/app/views/data/index.html.erb index a1edbda7..5fb93294 100644 --- a/app/views/data/index.html.erb +++ b/app/views/data/index.html.erb @@ -3,10 +3,10 @@

Exporting data

You can choose between the following formats:

diff --git a/app/views/feedlist/mobile_index.rhtml b/app/views/feedlist/mobile_index.rhtml index a8511e75..b8c64398 100644 --- a/app/views/feedlist/mobile_index.rhtml +++ b/app/views/feedlist/mobile_index.rhtml @@ -1,50 +1,32 @@

+
  • <%= rss_formatted_link({ :controller => 'todos', :action => 'index', :limit => 15 }) -%> + <%= text_formatted_link({ :controller => 'todos', :action => 'index', :limit => 15 }) -%> + <%= ical_formatted_link({ :controller => 'todos', :action => 'index', :limit => 15 }) -%> + Last 15 actions
  • +
  • <%= rss_formatted_link( { :controller => 'todos', :action => 'index' } ) -%> + <%= text_formatted_link( { :controller => 'todos', :action => 'index' } ) -%> + <%= ical_formatted_link( { :controller => 'todos', :action => 'index' } ) -%> + All actions
  • +
  • <%= rss_formatted_link({ :controller => 'todos', :action => 'index', :due => 0 }) -%> + <%= text_formatted_link({ :controller => 'todos', :action => 'index', :due => 0 }) -%> + <%= ical_formatted_link({ :controller => 'todos', :action => 'index', :due => 0 }) -%> + Actions due today or earlier
  • +
  • <%= rss_formatted_link({ :controller => 'todos', :action => 'index', :due => 6 }) -%> + <%= text_formatted_link({ :controller => 'todos', :action => 'index', :due => 6 }) -%> + <%= ical_formatted_link({ :controller => 'todos', :action => 'index', :due => 6 }) -%> + Actions due in 7 days or earlier
  • +
  • <%= rss_formatted_link({ :controller => 'todos', :action => 'index', :done => 7 }) -%> + <%= text_formatted_link({ :controller => 'todos', :action => 'index', :done => 7 }) -%> + Actions completed in the last 7 days
  • +
  • <%= rss_formatted_link({:controller => 'contexts', :action => 'index'}) -%> + <%= text_formatted_link({:controller => 'contexts', :action => 'index'}) -%> + All Contexts
  • +
  • <%= rss_formatted_link({:controller => 'projects', :action => 'index'}) -%> + <%= text_formatted_link({:controller => 'projects', :action => 'index'}) -%> + All Projects
  • +
  • <%= rss_formatted_link({:controller => 'projects', :action => 'index', :only_active_with_no_next_actions => true}) %> + <%= text_formatted_link({:controller => 'projects', :action => 'index', :only_active_with_no_next_actions => true}) %> + Active projects with no next actions
  • +
  • <%= text_formatted_link({:controller => 'projects', :action => 'index', :projects_and_actions => true}) %> + Active projects with their actions +
  • \ No newline at end of file diff --git a/app/views/layouts/mobile.m.erb b/app/views/layouts/mobile.m.erb index 7902bd05..1be4d590 100644 --- a/app/views/layouts/mobile.m.erb +++ b/app/views/layouts/mobile.m.erb @@ -1,37 +1,32 @@ - - - - <%= stylesheet_link_tag "mobile" %> - <%= @page_title %> - - - <% if !(@new_mobile || @edit_mobile) - if !@prefs.nil? %> -

    <%= @down_count %> <%= - user_time.strftime(@prefs.title_date_format) %>

    - <%= (link_to("Add new action", formatted_new_todo_path(:m))+" | ") unless @new_mobile -%> - <%= (link_to("Home", formatted_todos_path(:m))+" | ") unless @home -%> - <%= (link_to("Contexts", formatted_contexts_path(:m))+" | ") %> - <%= (link_to("Projects", formatted_projects_path(:m))+" | ") %> - <%= (link_to("Starred", {:action => "tag", :controller => "todos", :id => "starred.m"})) -%> - <% end - end %> - <%= render_flash -%> -
    - <%= yield %> -
    - <% if !@prefs.nil? %> - <%= link_to "Logout", formatted_logout_path(:format => 'm') %> | - <%= (link_to("Add new action", formatted_new_todo_path(:m))+" | ") unless @new_mobile -%> - <%= (link_to("Home", formatted_todos_path(:m))+" | ") unless @home -%> - <%= (link_to("Contexts", formatted_contexts_path(:m))+" | ") %> - <%= (link_to("Projects", formatted_projects_path(:m))+" | ") %> - <%= (link_to("Starred", {:action => "tag", :controller => "todos", :id => "starred.m"})+" | ") -%> - <%= (link_to("Tickler", {:action => "index", :controller => "tickler.m"})+" | ") -%> - <%= (link_to("Feeds", {:action => "index", :controller => "feeds.m"})) %> - <% end %> - <%= render :partial => "shared/mobile_footer" %> - - + + + +<%= stylesheet_link_tag "mobile"%> +<%= @page_title %> + +<% if !(@new_mobile || @edit_mobile) + if !@prefs.nil? -%> +

    <%= @down_count %> <%= + user_time.strftime(@prefs.title_date_format) -%>

    +<%= (link_to("Add new action", formatted_new_todo_path(:m))+" | ") unless @new_mobile -%> +<%= (link_to("Home", formatted_todos_path(:m))+" | ") unless @home -%> +<%= (link_to("Contexts", formatted_contexts_path(:m))+" | ") -%> +<%= (link_to("Projects", formatted_projects_path(:m))+" | ") -%> +<%= (link_to("Starred", {:action => "tag", :controller => "todos", :id => "starred.m"})) -%> +<% end + end -%><%= render_flash -%> +
    <%= yield -%> +
    <% if !@prefs.nil? -%> +<%= (link_to("Logout", formatted_logout_path(:format => 'm')) +" | ") -%> +<%= (link_to("Add new action", formatted_new_todo_path(:m))+" | ") unless @new_mobile -%> +<%= (link_to("Home", formatted_todos_path(:m))+" | ") unless @home -%> +<%= (link_to("Contexts", formatted_contexts_path(:m))+" | ") -%> +<%= (link_to("Projects", formatted_projects_path(:m))+" | ") -%> +<%= (link_to("Starred", {:action => "tag", :controller => "todos", :id => "starred.m"})+" | ") -%> +<%= (link_to("Tickler", {:action => "index", :controller => "tickler.m"})+" | ") -%> +<%= (link_to("Feeds", {:action => "index", :controller => "feeds.m"})) -%> +<% end -%> +<%= render :partial => "shared/mobile_footer" -%> + \ No newline at end of file diff --git a/app/views/layouts/standard.html.erb b/app/views/layouts/standard.html.erb index 2b2c168c..3f3e5b43 100644 --- a/app/views/layouts/standard.html.erb +++ b/app/views/layouts/standard.html.erb @@ -37,11 +37,10 @@ window.onload=function(){ <%= render :partial => "todos/todo", :collection => @not_done, :locals => { :parent_container_type => "project" } %> + <% if @not_done.empty? + # fix (hack) for #713 + set_behavior_for_delete_icon + set_behavior_for_star_icon + set_behavior_for_edit_icon + set_behavior_for_toggle_checkbox + end + -%> diff --git a/app/views/projects/index_mobile.rhtml b/app/views/projects/index_mobile.rhtml index 3d7578cd..a33dce05 100644 --- a/app/views/projects/index_mobile.rhtml +++ b/app/views/projects/index_mobile.rhtml @@ -1,8 +1,6 @@ -

    Active projects

    -<%= render :partial => 'mobile_project_listing', :collection => @active_projects%> - -

    Hidden projects

    -<%= render :partial => 'mobile_project_listing', :collection => @hidden_projects %> - -

    Completed projects

    -<%= render :partial => 'mobile_project_listing', :collection => @completed_projects %> +

    Active projects

    <%= + render :partial => 'mobile_project_listing', :collection => @active_projects%> +

    Hidden projects

    <%= + render :partial => 'mobile_project_listing', :collection => @hidden_projects %> +

    Completed projects

    <%= + render :partial => 'mobile_project_listing', :collection => @completed_projects %> \ No newline at end of file diff --git a/app/views/shared/_flash.rhtml b/app/views/shared/_flash.rhtml index 8e86733e..86f9fc2c 100644 --- a/app/views/shared/_flash.rhtml +++ b/app/views/shared/_flash.rhtml @@ -1,11 +1,9 @@
    -<% if flash.empty? %> +<% if flash.empty? -%> -<% else %> +<% else -%> <% flash.each do |key,value| -%> -

    - <%= value %> -

    +

    <%= value %>

    <% end -%> -<% end %> +<% end -%>
    \ No newline at end of file diff --git a/app/views/shared/_mobile_footer.rhtml b/app/views/shared/_mobile_footer.rhtml index 25b2b295..dca01d3d 100644 --- a/app/views/shared/_mobile_footer.rhtml +++ b/app/views/shared/_mobile_footer.rhtml @@ -1,3 +1 @@ - + \ No newline at end of file diff --git a/app/views/stats/show_selection_from_chart.html.erb b/app/views/stats/show_selection_from_chart.html.erb index 2ef5f4ec..3da85a4c 100644 --- a/app/views/stats/show_selection_from_chart.html.erb +++ b/app/views/stats/show_selection_from_chart.html.erb @@ -1,18 +1,18 @@ <%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => url_for(:action => @chart_name)} -%>
    -

    Click on a bar in the chart to update the actions below. Click <%=link_to "here", {:controller => "stats", :action => "index"} %> to return to the statistics page

    +

    Click on a bar in the chart to update the actions below. Click <%=link_to "here", {:controller => "stats", :action => "index"} %> to return to the statistics page. <% + unless @further -%> <%= + "Click " + + link_to("here", {:controller => "stats", :action => "show_selected_actions_from_chart", :id=>"#{params[:id]}_end", :index => params[:index]})+ + " to show the actions from week " + params[:index] + " and further." -%> + <% end %>


    -

    - <%= @page_title -%> -

    - +

    <%= @page_title -%>

    There are no actions selected

    - <%= render :partial => "todos/todo", :collection => @selected_actions, :locals => { :parent_container_type => 'stats' } %> -
    \ No newline at end of file diff --git a/app/views/todos/_edit_form.rhtml b/app/views/todos/_edit_form.rhtml index f0006730..8dc5beb9 100644 --- a/app/views/todos/_edit_form.rhtml +++ b/app/views/todos/_edit_form.rhtml @@ -11,7 +11,7 @@
    - +" />