diff --git a/tracks/app/controllers/application.rb b/tracks/app/controllers/application.rb index 9e462b05..068e8a88 100644 --- a/tracks/app/controllers/application.rb +++ b/tracks/app/controllers/application.rb @@ -56,8 +56,7 @@ class ApplicationController < ActionController::Base # Okay, you get another hour @session['expiry_time'] = Time.now + (60*60) end - end - end - - + end + end + end diff --git a/tracks/app/controllers/context_controller.rb b/tracks/app/controllers/context_controller.rb index 93c85113..4f21ddd2 100644 --- a/tracks/app/controllers/context_controller.rb +++ b/tracks/app/controllers/context_controller.rb @@ -1,8 +1,6 @@ class ContextController < ApplicationController - helper :context - model :project - model :todo + helper :todo before_filter :login_required layout "standard" @@ -57,19 +55,6 @@ class ContextController < ApplicationController render :text => "" end end - - # Toggles the 'done' status of the action - # - def toggle_check - self.init - - item = check_user_return_item - item.toggle!('done') - item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working - if item.save - render :partial => 'context/show_items', :object => item - end - end # Fairly self-explanatory; deletes the context # If the context contains actions, you'll get a warning dialogue. @@ -84,7 +69,7 @@ class ContextController < ApplicationController end end - # Methods for changing the sort order of the projects in the list + # Methods for changing the sort order of the contexts in the list # def order @params["list-contexts"].each_with_index do |id, position| @@ -96,16 +81,6 @@ class ContextController < ApplicationController end protected - def check_user_return_item - item = Todo.find( @params['id'] ) - if @session['user'] == item.user - return item - else - flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@session['user'].name}!" - render_text "" - end - end - def check_user_set_context @user = @session['user'] diff --git a/tracks/app/controllers/project_controller.rb b/tracks/app/controllers/project_controller.rb index e7cc7ce6..431b36b0 100644 --- a/tracks/app/controllers/project_controller.rb +++ b/tracks/app/controllers/project_controller.rb @@ -1,10 +1,10 @@ class ProjectController < ApplicationController - helper :project - model :context model :todo + helper :todo before_filter :login_required + layout "standard" def index @@ -75,19 +75,6 @@ class ProjectController < ApplicationController end end - # Toggles the 'done' status of the action - # - def toggle_check - self.init - - item = check_user_return_item - item.toggle!('done') - item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working - if item.save - render :partial => 'project/show_items', :object => item - end - end - # Toggles the 'done' status of a project # def toggle_project_done @@ -124,16 +111,6 @@ class ProjectController < ApplicationController protected - def check_user_return_item - item = Todo.find( @params['id'] ) - if @session['user'] == item.user - return item - else - flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@session['user'].name}!" - render_text "" - end - end - def check_user_set_project @user = @session['user'] if @params["name"] diff --git a/tracks/app/controllers/todo_controller.rb b/tracks/app/controllers/todo_controller.rb index 591233f2..06d6b50c 100644 --- a/tracks/app/controllers/todo_controller.rb +++ b/tracks/app/controllers/todo_controller.rb @@ -1,7 +1,10 @@ class TodoController < ApplicationController + model :user + model :project + model :context + helper :todo - model :context, :project, :user before_filter :login_required layout "standard" @@ -21,41 +24,13 @@ class TodoController < ApplicationController @page_title = "TRACKS::List tasks" @done = @done[0..(NO_OF_ACTIONS-1)] + @contexts_to_show = @contexts.clone + @contexts_to_show = @contexts_to_show.collect {|x| (!x.hidden? and !x.find_not_done_todos.empty?) ? x:nil }.compact + # Set count badge to number of not-done, not hidden context items @count = @todos.collect { |x| ( !x.done? and !x.context.hidden? ) ? x:nil }.compact.size end - # List the completed tasks, sorted by completion date - # - # Use days declaration? 1.day.ago? - def completed - self.init - @page_title = "TRACKS::Completed tasks" - - day = (60 * 60 * 24) - today = Time.now - - today_date = today - (1 * day) - week_begin = today - (1 * day) - week_end = today - (7 * day) - month_begin = today - (8 * day) - month_end = today - (31 * day) - - @done_today = @done.collect { |x| today_date <= x.completed ? x:nil }.compact - @done_this_week = @done.collect { |x| week_begin >= x.completed && week_end <= x.completed ? x:nil }.compact - @done_this_month = @done.collect { |x| month_begin >= x.completed && month_end <= x.completed ? x:nil }.compact - - end - - # Archived completed items, older than 31 days - # - def completed_archive - self.init - @page_title = "TRACKS::Archived completed tasks" - archive_date = Time.now - 32 * (60 * 60 * 24) - @done_archive = @done.collect { |x| archive_date >= x.completed ? x:nil }.compact - end - # Called by a form button # Parameters from form fields are passed to create new action # in the selected context. @@ -78,6 +53,26 @@ class TodoController < ApplicationController end end + def edit_action + self.init + + item = check_user_return_item + render :partial => 'action_edit_form', :object => item + end + + # Toggles the 'done' status of the action + # + def toggle_check + self.init + + item = check_user_return_item + item.toggle!('done') + item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working + if item.save + render :partial => 'item', :object => item + end + end + # Edit the details of an action # def update_action @@ -112,19 +107,38 @@ class TodoController < ApplicationController end end - # Toggles the 'done' status of the action + # List the completed tasks, sorted by completion date # - def toggle_check + # Use days declaration? 1.day.ago? + def completed self.init + @page_title = "TRACKS::Completed tasks" + + day = (60 * 60 * 24) + today = Time.now + + today_date = today - (1 * day) + week_begin = today - (1 * day) + week_end = today - (7 * day) + month_begin = today - (8 * day) + month_end = today - (31 * day) + + @done_today = @done.collect { |x| today_date <= x.completed ? x:nil }.compact + @done_this_week = @done.collect { |x| week_begin >= x.completed && week_end <= x.completed ? x:nil }.compact + @done_this_month = @done.collect { |x| month_begin >= x.completed && month_end <= x.completed ? x:nil }.compact - item = check_user_return_item - item.toggle!('done') - item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working - if item.save - render :partial => 'item', :object => item - end end + # Archived completed items, older than 31 days + # + def completed_archive + self.init + @page_title = "TRACKS::Archived completed tasks" + archive_date = Time.now - 32 * (60 * 60 * 24) + @done_archive = @done.collect { |x| archive_date >= x.completed ? x:nil }.compact + end + + protected def check_user_return_item @@ -145,6 +159,6 @@ class TodoController < ApplicationController @done = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = 1", @user.id], :include => [:project], :order => "completed DESC") # for some reason, this generates an error about anil object under 0.14.2 #@done = @todos.collect { |x| x.done? ? x:nil }.compact.sort! {|x,y| y.completed <=> x.completed } - end + end diff --git a/tracks/app/helpers/application_helper.rb b/tracks/app/helpers/application_helper.rb index 00dd1064..fd19812e 100644 --- a/tracks/app/helpers/application_helper.rb +++ b/tracks/app/helpers/application_helper.rb @@ -32,59 +32,4 @@ module ApplicationHelper name.to_s.gsub(/ /, "_") end - - # 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 "" - end - - @now = Date.today - @days = due-@now - - case @days - # overdue or due very soon! sound the alarm! - when -365..-1 - "Overdue by " + (@days * -1).to_s + " days " - when 0 - "Due Today " - when 1 - "Due Tomorrow " - # due 2-7 days away - when 2..7 - "Due in " + @days.to_s + " days " - # more than a week away - relax - else - "Due in " + @days.to_s + " days " - end - end - - # Uses the 'staleness_starts' value from settings.yml (in days) to colour - # the background of the action appropriately according to the age - # of the creation date: - # * l1: created more than 1 x staleness_starts, but < 2 x staleness_starts - # * l2: created more than 2 x staleness_starts, but < 3 x staleness_starts - # * l3: created more than 3 x staleness_starts - # - def staleness(item) - if item.created_at < (ApplicationController::STALENESS_STARTS*3).days.ago - return "
" - elsif item.created_at < (ApplicationController::STALENESS_STARTS*2).days.ago - return "
" - elsif item.created_at < (ApplicationController::STALENESS_STARTS).days.ago - return "
" - else - return "
" - end - end - - def calendar_setup( input_field ) - str = "Calendar.setup({ ifFormat:\"#{ApplicationController::DATE_FORMAT}\"" - str << ",firstDay:#{ApplicationController::WEEK_STARTS_ON},showOthers:true,range:[2004, 2010]" - str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })" - javascript_tag str - end - end diff --git a/tracks/app/helpers/todo_helper.rb b/tracks/app/helpers/todo_helper.rb index 0b4096b8..d00d8349 100644 --- a/tracks/app/helpers/todo_helper.rb +++ b/tracks/app/helpers/todo_helper.rb @@ -1,29 +1,36 @@ module TodoHelper - # Counts the number of uncompleted items in the selected context + # Counts the number of uncompleted items in the specified context # def count_items(context) count = Todo.find_all("done=0 AND context_id=#{context.id}").length end - def form_remote_tag_todo_notdone( item ) - form_remote_tag( :url => url_for( :controller => "todo", :action => "toggle_check", :id => item.id ), - :html => { :id=> "checkbox-notdone-#{item.id}", :class => "inline-form" }, - :update => "completed", - :position => "top", - :loading => "Form.disable('checkbox-notdone-#{item.id}');", - :complete => visual_effect(:fade, "item-#{item.id}-container") - ) - end + def form_remote_tag_toggle_todo( item ) + target_div = item.done? ? "new_actions" : "completed" + target_position = item.done? ? "bottom" : "top" + form_id = "checkbox-#{item.id}-form" + item_container_id = "item-#{item.id}-container" + + loading_javascript = "Form.disable('#{form_id}');" + if item.done? + loading_javascript << visual_effect(:appear, "new_actions", :duration => 0.4) + end + + success_javascript = " $('#{item_container_id}').setAttribute('id','#{item_container_id}-fading');" + success_javascript << visual_effect( :fade, "#{item_container_id}-fading", + { + :duration => 0.4, + :afterFinish => "function(effect) { Element.remove('#{item_container_id}-fading'); }" + }) - def form_remote_tag_todo_done( item ) form_remote_tag( :url => url_for( :controller => "todo", :action => "toggle_check", :id => item.id ), - :html => { :id=> "checkbox-done-#{item.id}", :class => "inline-form" }, - :update => "new_actions", - :position => "bottom", - :loading => "Form.disable('checkbox-done-#{item.id}');", - :complete => "Element.toggle('new_actions');new Effect.Fade('done-item-#{item.id}-container');" - ) + :html => { :id=> "#{form_id}", :class => "inline-form item-checkmark-form" }, + :update => target_div, + :position => target_position, + :loading => loading_javascript, + :success => success_javascript, + :complete => visual_effect( :highlight, item_container_id)) end def form_remote_tag_edit_todo( item ) @@ -33,27 +40,82 @@ module TodoHelper :complete => visual_effect(:appear, "item-#{item.id}-container") ) end - - def link_to_remote_todo_notdone( item ) - str = "Element.toggle('item-#{item.id}','action-#{item.id}-edit-form');" - str << " new Effect.Appear('action-#{item.id}-edit-form');" - str << " Form.focusFirstElement('form-action-#{item.id}')" - link_to_remote( image_tag("blank", :title =>"Delete action", :class=>"delete_item"), - :update => "item-#{item.id}-container", - :loading => visual_effect(:fade, "item-#{item.id}-container"), - :url => { :controller => "todo", :action => "destroy_action", :id => item.id }, - :confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?") + " " + - link_to_function(image_tag( "blank", :title => "Edit action", :class => "edit_item"), - str ) + " " + + def link_to_remote_todo( item ) + str = link_to_remote( image_tag("blank", :title =>"Delete action", :class=>"delete_item"), + { + :update => "item-#{item.id}-container", + :loading => visual_effect(:fade, "item-#{item.id}-container"), + :url => { :controller => "todo", :action => "destroy_action", :id => item.id }, + :confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?" + }, + { + :class => "icon" + }) + "\n" + if !item.done? + str << link_to_remote( image_tag("blank", :title =>"Edit action", :class=>"edit_item", :id=>"action-#{item.id}-edit-icon"), + { + :update => "form-action-#{item.id}", + :loading => visual_effect(:pulsate, "action-#{item.id}-edit-icon"), + :url => { :controller => "todo", :action => "edit_action", :id => item.id }, + :success => "Element.toggle('item-#{item.id}','action-#{item.id}-edit-form'); new Effect.Appear('action-#{item.id}-edit-form', { duration: .2 }); Form.focusFirstElement('form-action-#{item.id}')" + }, + { + :class => "icon" + }) + else + str << '' + image_tag("blank") + " " + end + str + end + + # Uses the 'staleness_starts' value from settings.yml (in days) to colour + # the background of the action appropriately according to the age + # of the creation date: + # * l1: created more than 1 x staleness_starts, but < 2 x staleness_starts + # * l2: created more than 2 x staleness_starts, but < 3 x staleness_starts + # * l3: created more than 3 x staleness_starts + # + def staleness_class(item) + if item.due || item.done + return "" + elsif item.created_at < (ApplicationController::STALENESS_STARTS*3).days.ago + return " stale_l3" + elsif item.created_at < (ApplicationController::STALENESS_STARTS*2).days.ago + return " stale_l2" + elsif item.created_at < (ApplicationController::STALENESS_STARTS).days.ago + return " stale_l1" + else + return "" + end end - def link_to_remote_todo_done( item ) - link_to_remote( image_tag("blank", :title =>"Delete action", :class=>"delete_item"), - :update => "done-item-#{item.id}-container", - :loading => visual_effect(:fade, "done-item-#{item.id}-container"), - :url => { :controller => "todo", :action => "destroy_action", :id => item.id }, - :confirm => "Are you sure that you want to delete the action \'#{item.description}\'?" ) + - "" + image_tag("blank") + " " + # 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 "" + end + + @now = Date.today + @days = due-@now + + case @days + # overdue or due very soon! sound the alarm! + when -365..-1 + "Overdue by " + (@days * -1).to_s + " days " + when 0 + "Due Today " + when 1 + "Due Tomorrow " + # due 2-7 days away + when 2..7 + "Due in " + @days.to_s + " days " + # more than a week away - relax + else + "Due in " + @days.to_s + " days " + end end def toggle_show_notes( item ) @@ -62,8 +124,16 @@ module TodoHelper str << "')\" class=\"show_notes\" title=\"Show notes\">" str << image_tag( "blank", :width=>"16", :height=>"16", :border=>"0" ) + "" m_notes = markdown( item.notes ) - str << "
" + str << "\n
" str << m_notes + "
" str end + + def calendar_setup( input_field ) + str = "Calendar.setup({ ifFormat:\"#{ApplicationController::DATE_FORMAT}\"" + str << ",firstDay:#{ApplicationController::WEEK_STARTS_ON},showOthers:true,range:[2004, 2010]" + str << ",step:1,inputField:\"" + input_field + "\",cache:true,align:\"TR\" })" + javascript_tag str + end + end diff --git a/tracks/app/views/context/show.rhtml b/tracks/app/views/context/show.rhtml index 9186318d..e0461ef8 100644 --- a/tracks/app/views/context/show.rhtml +++ b/tracks/app/views/context/show.rhtml @@ -1,42 +1,7 @@
-
-

<%= sanitize(@context.name) %>

- -
- <% if @not_done.empty? -%> -
- <%= render :partial => "empty", - :locals => { :message => "There are currently no uncompleted actions in this context"} %> -
- <% else -%> - - <% end -%> - <%= render :partial => "show_items", :collection => @not_done %> -
-
- -
-

Completed actions in this context

- -
- <% if @done.empty? %> -
- <%= render :partial => "empty", - :locals => {:message => "There are currently no completed next actions in this context"} %> -
- <% else -%> - - <% end -%> - <%= render :partial => "show_items", :collection => @done %> -
-
+<%= render :partial => "context/context", :locals => { :context => @context, :collapsible => false } %> +<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this context" } %>
diff --git a/tracks/app/views/layouts/standard.rhtml b/tracks/app/views/layouts/standard.rhtml index 3f103ec3..dbdc8c6e 100644 --- a/tracks/app/views/layouts/standard.rhtml +++ b/tracks/app/views/layouts/standard.rhtml @@ -9,6 +9,7 @@ <%= stylesheet_link_tag 'calendar-system.css' %> <%= javascript_include_tag 'calendar', 'calendar-en', 'calendar-setup' %> <%= javascript_include_tag "accesskey-hints" %> + <%= javascript_include_tag "todo-items" %> <%= auto_discovery_link_tag(:rss,{:controller => "feed", :action => "na_feed", :name => "#{@session['user']['login']}", :token => "#{@session['user']['word']}"}, {:title => "RSS feed of next actions"}) %> diff --git a/tracks/app/views/note/_notes.rhtml b/tracks/app/views/note/_notes.rhtml index 5b15204d..cbb3a936 100644 --- a/tracks/app/views/note/_notes.rhtml +++ b/tracks/app/views/note/_notes.rhtml @@ -8,11 +8,11 @@ diff --git a/tracks/app/views/note/_notes_summary.rhtml b/tracks/app/views/note/_notes_summary.rhtml index 752aa4e3..eb597f30 100644 --- a/tracks/app/views/note/_notes_summary.rhtml +++ b/tracks/app/views/note/_notes_summary.rhtml @@ -1,7 +1,7 @@ <% note = notes_summary -%>
-<%= link_to( image_tag("blank"), { :controller => "note", :action => "show", - :id => note.id}, :title => "Show note", :class => "show_notes" ) %>  +<%= link_to( image_tag("blank", :border => 0), { :controller => "note", :action => "show", + :id => note.id}, :title => "Show note", :class => "show_notes icon") %>  <%= sanitize(textilize(truncate(note.body, 50, "..."))) %>
<% note = nil -%> diff --git a/tracks/app/views/note/index.rhtml b/tracks/app/views/note/index.rhtml index 9638074c..03919b43 100644 --- a/tracks/app/views/note/index.rhtml +++ b/tracks/app/views/note/index.rhtml @@ -1,6 +1,6 @@
<% for notes in @all_notes -%> -
+
<%= render_partial "notes", notes %>
<% end -%> diff --git a/tracks/app/views/note/show.rhtml b/tracks/app/views/note/show.rhtml index 5a350a1a..157ce3b4 100644 --- a/tracks/app/views/note/show.rhtml +++ b/tracks/app/views/note/show.rhtml @@ -1,5 +1,5 @@
-
+
<%= render_partial "notes", @note %>
\ No newline at end of file diff --git a/tracks/app/views/project/show.rhtml b/tracks/app/views/project/show.rhtml index d8d760d5..ba478be9 100644 --- a/tracks/app/views/project/show.rhtml +++ b/tracks/app/views/project/show.rhtml @@ -1,51 +1,18 @@
-
-

<%= sanitize(@project.name) %>

-<% if @project.description -%> -
<%= sanitize(@project.description) %>
-<% end -%> +<%= render :partial => "project/project", :locals => { :project => @project, :collapsible => false } %> +<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this project" } %> - <% if @msg_nd -%> -
-

<%= @msg_nd %>

-
- <% end -%> - -
- <% if @project.done? -%> -

Project has been marked as completed

- <% end -%> - <%= render :partial => "show_items", :collection => @not_done %> -
-
- -
-

Completed actions in this project

- -
- <% if @msg_d -%> -
-

<%= @msg_d %>

-
- <% end -%> - <%= render :partial => "show_items", :collection => @done %> -
-
- - -
+

Notes

- <% if @msg_n -%> -
-

<%= @msg_n %>

-
- <% end -%> +
+ <%= render :partial => "shared/empty", + :locals => { :message => "Currently there are no notes attached to this project"} %> +
<%= render :partial => "note/notes_summary", :collection => @notes %>
- <% if @project.done? -%> <%= button_to "Mark project as uncompleted", {:action => "toggle_project_done", :id => @project.id} %>
@@ -59,8 +26,7 @@ <%= form_remote_tag :url => { :controller => "note", :action => "add" }, :update => "notes", :position => "bottom", - :complete => "new Effect.Highlight('notes'); - Element.hide('message-notes');", + :complete => "new Effect.Highlight('notes');", :html => {:id=>'form-new-note', :class => 'inline-form'} %> <%= hidden_field( "new_note", "project_id", "value" => "#{@project.id}" ) %> <%= text_area( "new_note", "body", "cols" => 50, "rows" => 3, "tabindex" => 1 ) %> diff --git a/tracks/app/views/shared/add_new_item_form.rhtml b/tracks/app/views/shared/add_new_item_form.rhtml index e5b94fdc..be953fac 100644 --- a/tracks/app/views/shared/add_new_item_form.rhtml +++ b/tracks/app/views/shared/add_new_item_form.rhtml @@ -2,10 +2,10 @@ case controller.controller_name when "context" add_string = "Add a next action in this context »" - update_div = "next_actions" + update_div = "c" + @context.id.to_s when "project" add_string = "Add a next action in this project »" - update_div = "next_actions" + update_div = "p" + @project.id.to_s else add_string = "Add a next action »" update_div = "new_actions" @@ -14,7 +14,7 @@ <%= link_to_function( add_string, -"Element.toggle('todo_new_action');Form.focusFirstElement('todo-form-new-action');Element.toggle('new_actions');", +"Element.toggle('todo_new_action');Form.focusFirstElement('todo-form-new-action');", {:title => "Add the next action", :accesskey => "n"}) %>