diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index e2bac2ce..beceb67a 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -2,8 +2,8 @@ class TodosController < ApplicationController
helper :todos
- skip_before_filter :login_required, :only => [:index]
- prepend_before_filter :login_or_feed_token_required, :only => [:index]
+ skip_before_filter :login_required, :only => [:index, :calendar]
+ prepend_before_filter :login_or_feed_token_required, :only => [:index, :calendar]
append_before_filter :init, :except => [ :destroy, :completed, :completed_archive, :check_deferred, :toggle_check, :toggle_star, :edit, :update, :create, :calendar ]
append_before_filter :get_todo_from_params, :only => [ :edit, :toggle_check, :toggle_star, :show, :update, :destroy ]
@@ -172,6 +172,7 @@ class TodosController < ApplicationController
@original_item_context_id = @todo.context_id
@original_item_project_id = @todo.project_id
@original_item_was_deferred = @todo.deferred?
+ @original_item_due = @todo.due
if params['todo']['project_id'].blank? && !params['project_name'].nil?
if params['project_name'] == 'None'
project = Project.null_object
@@ -222,6 +223,25 @@ class TodosController < ApplicationController
@context_changed = @original_item_context_id != @todo.context_id
@todo_was_activated_from_deferred_state = @original_item_was_deferred && @todo.active?
+ @due_date_changed = @original_item_due != @todo.due
+ if @due_date_changed
+ due_today_date = Time.zone.now
+ due_this_week_date = Time.zone.now.end_of_week
+ due_next_week_date = due_this_week_date + 7.days
+ due_this_month_date = Time.zone.now.end_of_month
+ if @todo.due <= due_today_date
+ @new_due_id = "due_today"
+ elsif @todo.due <= due_this_week_date
+ @new_due_id = "due_this_week"
+ elsif @todo.due <= due_next_week_date
+ @new_due_id = "due_next_week"
+ elsif @todo.due <= due_this_month_date
+ @new_due_id = "due_this_month_week"
+ else
+ @new_due_id = "due_after_this_month"
+ end
+ end
+
if @context_changed
determine_remaining_in_context_count(@original_item_context_id)
else
@@ -432,7 +452,12 @@ class TodosController < ApplicationController
respond_to do |format|
format.html
- format.ics { render :text => 'Not implemented yet', :status => 200 }
+ 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")
+ render :action => 'calendar', :layout => false, :content_type => Mime::ICS
+ }
end
end
diff --git a/app/views/layouts/standard.html.erb b/app/views/layouts/standard.html.erb
index 21c9cdc4..42ea20d2 100644
--- a/app/views/layouts/standard.html.erb
+++ b/app/views/layouts/standard.html.erb
@@ -54,6 +54,7 @@ window.onload=function(){
<% if current_user.is_admin? -%>
<%= navigation_link("Admin", users_path, {:accesskey => "a", :title => "Add or delete users"} ) %>
<% end -%>
+ <%= navigation_link(image_tag("x-office-calendar.png", :size => "16X16", :border => 0), calendar_path, :title => "Calendar of due actions" ) %>
<%= navigation_link(image_tag("recurring_menu16x16.png", :size => "16X16", :border => 0), {:controller => "recurring_todos", :action => "index"}, :title => "Manage recurring actions" ) %>
<%= navigation_link(image_tag("feed-icon.png", :size => "16X16", :border => 0), {:controller => "feedlist", :action => "index"}, :title => "See a list of available feeds" ) %>
<%= navigation_link(image_tag("menustar.gif", :size => "16X16", :border => 0), tag_path("starred"), :title => "See your starred actions" ) %>
diff --git a/app/views/todos/calendar.html.erb b/app/views/todos/calendar.html.erb
index f887ffac..29860508 100644
--- a/app/views/todos/calendar.html.erb
+++ b/app/views/todos/calendar.html.erb
@@ -2,33 +2,50 @@
Due today
- <%= render :partial => "todos/todo", :collection => @due_today %>
+
+ <%= render :partial => "todos/todo", :collection => @due_today %>
+
-
Due this week
- <%= render :partial => "todos/todo", :collection => @due_this_week %>
+
Due in rest of this week
+
+ <%= render :partial => "todos/todo", :collection => @due_this_week %>
+
Due next week
- <%= render :partial => "todos/todo", :collection => @due_next_week %>
+
+ <%= render :partial => "todos/todo", :collection => @due_next_week %>
+
-
Due rest of this month
- <%= render :partial => "todos/todo", :collection => @due_this_month %>
+
Due in rest of this month
+
+ <%= render :partial => "todos/todo", :collection => @due_this_month %>
+
Due next month and later
- <%= render :partial => "todos/todo", :collection => @due_after_this_month %>
+
+ <%= render :partial => "todos/todo", :collection => @due_after_this_month %>
+
-
+
+<%
+apply_behavior 'input.hide_tickler:click', :prevent_default => true do |page|
+ page << "alert('hiding action in tickler from calendar is not yet implemented');"
+end
+%>
\ No newline at end of file
diff --git a/app/views/todos/calendar.ics.erb b/app/views/todos/calendar.ics.erb
new file mode 100644
index 00000000..af9d7682
--- /dev/null
+++ b/app/views/todos/calendar.ics.erb
@@ -0,0 +1,25 @@
+BEGIN:VCALENDAR
+PRODID:-//TRACKS//<%= TRACKS_VERSION %>//EN
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:PUBLISH
+X-WR-CALNAME:Tracks
+<% for todo in @due_all -%>
+BEGIN:VEVENT
+DTSTART;VALUE=DATE:<%= todo.due.strftime("%Y%m%d") %>
+DTEND;VALUE=DATE:<%= (todo.due+1.day).strftime("%Y%m%d") %>
+DTSTAMP:<%= todo.due.strftime("%Y%m%dT%H%M%SZ") %>
+UID:<%= todo_url(todo) %>
+CLASS:PUBLIC
+CATEGORIES:Tracks
+CREATED:<%= todo.created_at.strftime("%Y%m%dT%H%M%SZ") %>
+DESCRIPTION:<%= format_ical_notes(todo.notes) %>
+LAST-MODIFIED:<%= todo.due.strftime("%Y%m%dT%H%M%SZ") %>
+LOCATION:
+SEQUENCE:0
+STATUS:CONFIRMED
+SUMMARY:<%= todo.description %>
+TRANSP:TRANSPARENT
+END:VEVENT
+<% end -%>
+END:VCALENDAR
\ No newline at end of file
diff --git a/app/views/todos/update.js.rjs b/app/views/todos/update.js.rjs
index dae71f41..a5c8e147 100644
--- a/app/views/todos/update.js.rjs
+++ b/app/views/todos/update.js.rjs
@@ -101,6 +101,12 @@ if @saved
elsif source_view_is :stats
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
+ elsif source_view_is :calendar
+ if @due_date_changed
+ page[@todo].remove
+ page.insert_html :bottom, @new_due_id, :partial => 'todos/todo'
+ page.visual_effect :highlight, dom_id(@todo), :duration => 3
+ end
else
logger.error "unexpected source_view '#{params[:_source_view]}'"
end
diff --git a/config/routes.rb b/config/routes.rb
index 222f7619..50e29ff7 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -46,6 +46,7 @@ ActionController::Routing::Routes.draw do |map|
todos.tag 'todos/tag/:name.m', :action => "tag", :format => 'm'
todos.tag 'todos/tag/:name', :action => "tag", :name => /.*/
+ todos.calendar 'calendar.ics', :action => "calendar", :format => 'ics'
todos.calendar 'calendar', :action => "calendar"
todos.mobile 'mobile', :action => "index", :format => 'm'
diff --git a/public/images/x-office-calendar.png b/public/images/x-office-calendar.png
new file mode 100644
index 00000000..f8607e33
Binary files /dev/null and b/public/images/x-office-calendar.png differ