Make Todo routes RESTful.

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@406 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-01-25 07:07:10 +00:00
parent b2ce323f3a
commit fedf029764
40 changed files with 98 additions and 65 deletions

View file

@ -41,7 +41,7 @@ class AdminController < ApplicationController
def admin_login_required
unless User.find_by_id_and_is_admin(session['user_id'], true)
notify :error, "Only admin users are allowed access to this function"
redirect_to :controller => 'todo', :action => 'index'
redirect_to home_path
return false
end
end

View file

@ -1,6 +1,6 @@
class ContextsController < ApplicationController
helper :todo
helper :todos
before_filter :init, :except => [:create, :destroy, :order]
before_filter :init_todos, :only => :show

View file

@ -18,7 +18,7 @@ class LoginController < ApplicationController
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 }
redirect_back_or_default :controller => "todo", :action => "index"
redirect_back_or_default home_url
else
@login = params['user_login']
notify :warning, "Login unsuccessful"
@ -69,7 +69,7 @@ class LoginController < ApplicationController
unless (@user.nil?)
notify :notice, "You have successfully verified #{open_id_response.identity_url} as your identity."
session['user_id'] = @user.id
redirect_back_or_default :controller => 'todo', :action => 'index'
redirect_back_or_default home_path
else
notify :warning, "You have successfully verified #{open_id_response.identity_url} as your identity, but you do not have a Tracks account. Please ask your administrator to sign you up."
end
@ -111,7 +111,7 @@ class LoginController < ApplicationController
@user.create_preference
@user.save
notify :notice, "Signup successful for user #{@user.login}."
redirect_back_or_default :controller => "todo", :action => "index"
redirect_back_or_default home_url
end
end
@ -121,7 +121,7 @@ class LoginController < ApplicationController
# TODO: Maybe it would be better to mark deleted. That way user deletes can be reversed.
@user.destroy
end
redirect_back_or_default :controller => "todo", :action => "index"
redirect_back_or_default home_url
end
def logout

View file

@ -1,6 +1,6 @@
class ProjectsController < ApplicationController
helper :todo, :notes
helper :todos, :notes
before_filter :init, :except => [:create, :destroy, :order]
def index

View file

@ -1,6 +1,6 @@
class TodoController < ApplicationController
class TodosController < ApplicationController
helper :todo
helper :todos
append_before_filter :init, :except => [ :destroy, :completed, :completed_archive, :check_tickler ]
layout 'standard'
@ -222,7 +222,7 @@ class TodoController < ApplicationController
@done_archive = @done.completed_more_than 28.day.ago.utc
end
def tickler
def list_deferred
@source_view = 'deferred'
@page_title = "TRACKS::Tickler"
@tickles = @user.deferred_todos
@ -234,15 +234,15 @@ class TodoController < ApplicationController
def check_tickler
@due_tickles = @user.deferred_todos.find_and_activate_ready
respond_to do |format|
format.html { redirect_to :controller => 'todo', :action => 'index' }
format.html { redirect_to home_path }
format.js
end
end
# /todo/tag/[tag_name] shows all the actions tagged with tag_name
# /todos/tag/[tag_name] shows all the actions tagged with tag_name
#
def tag
@tag = tag_name = params[:id]
@tag = tag_name = params[:name]
if Tag.find_by_name(tag_name)
@todos = Todo.find_tagged_with(tag_name, @user)
else

View file

@ -63,7 +63,7 @@ module FeedHelper
end
def format_ical_uid(todo)
sprintf("%s%s%s%s", @request.protocol, @request.host, @request.port_string, url_for(:controller => 'todo', :action => 'show', :id => todo.id))
sprintf("%s%s%s%s", @request.protocol, @request.host, @request.port_string, todo_url(todo))
end
end

View file

@ -1,4 +1,4 @@
module TodoHelper
module TodosHelper
require 'user_controller'
# Counts the number of uncompleted items in the specified context
@ -8,22 +8,25 @@ module TodoHelper
end
def form_remote_tag_edit_todo( item, &block )
form_remote_tag( :url => { :controller => 'todo', :action => 'update', :id => item.id },
form_remote_tag( :url => todo_path(item), :method => :put,
:html => { :id => dom_id(item, 'form'), :class => "inline-form" }, &block
)
end
def link_to_remote_todo(item)
url_options = { :controller => 'todo', :action => 'destroy', :id => item.id, :_source_view => @source_view }
itemurl = todo_path(:id => item.id, :_source_view => @source_view)
str = link_to_remote( image_tag_for_delete,
{ :url => url_options, :confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?" },
{ :url => todo_path(:id => item.id, :_source_view => @source_view),
:method => :delete,
:confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?" },
{ :class => "icon" }
) + "\n"
if !item.completed?
url_options[:action] = 'edit'
str << link_to_remote( image_tag_for_edit(item),
{ :url => url_options, :loading => visual_effect(:pulsate, dom_id(item, 'edit_icon')) },
{ :url => edit_todo_path(:id => item.id, :_source_view => @source_view),
:method => 'get',
:loading => visual_effect(:pulsate, dom_id(item, 'edit_icon')) },
{ :class => "icon" }
)
else

View file

@ -14,6 +14,6 @@
<div id="c<%= context.id %>empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
<div class="message"><p>Currently there are no uncompleted actions in this context</p></div>
</div>
<%= render :partial => "todo/item", :collection => @not_done, :locals => { :parent_container_type => "context" } %>
<%= render :partial => "todos/item", :collection => @not_done, :locals => { :parent_container_type => "context" } %>
</div><!-- [end:items] -->
</div><!-- [end:c<%= context.id %>] -->

View file

@ -1,6 +1,6 @@
<div id="display_box">
<%= render :partial => "contexts/context", :locals => { :context => @context, :collapsible => false } %>
<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this context (last #{@user.prefs.show_number_completed})" } %>
<%= render :partial => "todos/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this context (last #{@user.prefs.show_number_completed})" } %>
</div><!-- [end:display_box] -->

View file

@ -1,7 +1,7 @@
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.channel do
xml.title(@title)
xml.link("http://#{request.host}:#{request.port}/todo/list")
xml.link("http://#{request.host}:#{request.port}/todos/list")
xml.description(@description)
@todos.each do |i|
xml.item do
@ -9,7 +9,7 @@ xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.link(context_url(i.context))
item_notes = sanitize(markdown( i.notes )) if i.notes?
due = "<div>Due: #{format_date(i.due)}</div>\n" if i.due?
toggle_link = link_to( "mark as done", {:only_path => false, :controller => "todo", :action => "toggle_check", :id => i.id})
toggle_link = link_to( "mark as done", {:only_path => false, :controller => "todos", :action => "toggle_check", :id => i.id})
done = "<div>#{toggle_link}</div>" unless i.completed?
done = "<div>Completed: #{format_date(i.completed_at)}</div>\n" if i.completed?
context_link = link_to( i.context.name, context_url(i.context) )

View file

@ -40,11 +40,11 @@
<div id="navcontainer">
<ul id="navlist">
<li><%= navigation_link("Home", {:controller => "todo", :action => "index"}, {:accesskey => "t", :title => "Home"} ) %></li>
<li><%= navigation_link("Home", home_path, {:accesskey => "t", :title => "Home"} ) %></li>
<li><%= navigation_link( "Contexts", contexts_path, {:accesskey=>"c", :title=>"Contexts"} ) %></li>
<li><%= navigation_link( "Projects", projects_path, {:accesskey=>"p", :title=>"Projects"} ) %></li>
<li><%= navigation_link( "Tickler", {:controller => "todo", :action => "tickler"}, :title => "Tickler" ) %></li>
<li><%= navigation_link( "Done", {:controller => "todo", :action => "completed"}, {:accesskey=>"d", :title=>"Completed"} ) %></li>
<li><%= navigation_link( "Tickler", tickler_path, :title => "Tickler" ) %></li>
<li><%= navigation_link( "Done", done_path, {:accesskey=>"d", :title=>"Completed"} ) %></li>
<li><%= navigation_link( "Notes", notes_path, {:accesskey => "o", :title => "Show all notes"} ) %></li>
<li><%= navigation_link( "Preferences", {:controller => "preferences", :action => "index"}, {:accesskey => "u", :title => "Show my preferences"} ) %></li>
<li><%= navigation_link( "Import/Export", {:controller => "data", :action => "index"}, {:accesskey => "i", :title => "Import and export data"} ) %></li>
@ -64,7 +64,7 @@
<%= periodically_call_remote( :url => {:controller => "login", :action => "check_expiry"},
:frequency => (5*60)) %>
<% end -%>
<%= periodically_call_remote( :url => {:controller => "todo", :action => "check_tickler"},
<%= periodically_call_remote( :url => check_tickler_path,
:frequency => (10*60)) %>
<%= yield %>
</div>

View file

@ -20,6 +20,6 @@
<div id="p<%= project.id %>empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
<div class="message"><p>Currently there are no uncompleted actions in this project</p></div>
</div>
<%= render :partial => "todo/item", :collection => @not_done, :locals => { :parent_container_type => "project" } %>
<%= render :partial => "todos/item", :collection => @not_done, :locals => { :parent_container_type => "project" } %>
</div><!-- [end:items] -->
</div><!-- [end:p<%= project.id %>] -->

View file

@ -1,8 +1,8 @@
<div id="display_box">
<%= render :partial => "projects/project", :locals => { :project => @project, :collapsible => false } %>
<%= render :partial => "todo/deferred", :locals => { :deferred => @deferred, :collapsible => false, :append_descriptor => "in this project" } %>
<%= render :partial => "todo/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this project" } %>
<%= render :partial => "todos/deferred", :locals => { :deferred => @deferred, :collapsible => false, :append_descriptor => "in this project" } %>
<%= render :partial => "todos/completed", :locals => { :done => @done, :collapsible => false, :append_descriptor => "in this project" } %>
<div class="container">
<div id="notes">

View file

@ -12,7 +12,7 @@
<!--[form:todo]-->
<% form_remote_tag(
:url => { :controller => "todo", :action => "create" },
:url => todos_path, :method => :post,
:html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form' }) do -%>
<div id="status"><%= error_messages_for("item") %></div>

View file

@ -12,6 +12,6 @@
<div class="message"><p>Currently there are no completed actions.</p></div>
</div>
<%= render :partial => "todo/item", :collection => done, :locals => { :parent_container_type => "completed" } %>
<%= render :partial => "todos/item", :collection => done, :locals => { :parent_container_type => "completed" } %>
</div>
</div><!-- [end:next_actions] -->

View file

@ -12,7 +12,7 @@
<div class="message"><p>Currently there are no deferred actions</p></div>
</div>
<%= render :partial => "todo/item", :collection => deferred, :locals => { :parent_container_type => 'tickler' } %>
<%= render :partial => "todos/item", :collection => deferred, :locals => { :parent_container_type => 'tickler' } %>
</div><!-- [end:items] -->
</div><!-- [end:tickler] -->

View file

@ -15,7 +15,7 @@
<% end %>
<% if done.notes? -%>
<%= render :partial => "todo/toggle_notes", :locals => { :item => done } %>
<%= render :partial => "todos/toggle_notes", :locals => { :item => done } %>
<% end -%>
</td>
<% end %>

View file

@ -4,7 +4,7 @@
<% unless source_view_is :deferred -%>
<input type="checkbox" class="item-checkbox"
onclick="new Ajax.Request('<%= url_for :controller => 'todo', :action => 'toggle_check', :id => item.id, :_source_view => @source_view %>', {asynchronous:true, evalScripts:true});"
onclick="new Ajax.Request('<%= toggle_check_todo_path(:id => item.id, :_source_view => @source_view) %>', {asynchronous:true, evalScripts:true});"
name="item_id" value="<%= item.id %>"<% if item.completed? %> checked="checked" <% end %> />
<% end -%>
@ -50,7 +50,7 @@
<% end -%>
<% if item.notes? -%>
<%= render :partial => "todo/toggle_notes", :locals => { :item => item } %>
<%= render :partial => "todos/toggle_notes", :locals => { :item => item } %>
<% end -%>
</div>
</div><!-- [end:<%= dom_id(item, 'line') %>] -->

View file

@ -21,5 +21,5 @@
</table>
</div>
<p>Older completed items: <%= link_to( "Older than 31 days", :controller => "todo", :action => "completed_archive" ) %></p>
<p>Older completed items: <%= link_to( "Older than 31 days", done_archive_path ) %></p>
</div><!-- End of display_box -->

View file

@ -14,7 +14,7 @@ if @saved
page.insert_html :top, 'display_box', :partial => 'contexts/context', :locals => { :context => @item.context, :collapsible => true }
else
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@item.context_id}" if source_view_is(:todo)
page.insert_html :bottom, item_container_id, :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type, :source_view => @source_view }
page.insert_html :bottom, item_container_id, :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type, :source_view => @source_view }
page.visual_effect :highlight, dom_id(@item), :duration => 3
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
end

View file

@ -1,4 +1,4 @@
page[dom_id(@item, 'form')].replace_html :partial => 'todo/edit_form'
page[dom_id(@item, 'form')].replace_html :partial => 'todos/edit_form'
page[dom_id(@item, 'line')].hide
page[dom_id(@item, 'edit')].show
page.call "Form.focusFirstElement", dom_id(@item, 'form')

View file

@ -3,7 +3,7 @@
<%= render :partial => "contexts/context", :collection => @contexts_to_show,
:locals => { :collapsible => true } %>
<% unless @done.nil? -%>
<%= render :partial => "todo/completed",
<%= render :partial => "todos/completed",
:locals => { :done => @done, :collapsible => true, :append_descriptor => nil } %>
<% end -%>
</div><!-- End of display_box -->

View file

@ -0,0 +1,21 @@
<div id="display_box">
<div id="tickler" class="container project">
<h2>Deferred actions</h2>
<div id="tickler-items" class="items toggle_target">
<div id="tickler-empty-nd" style="display:<%= @tickles.empty? ? 'block' : 'none'%>;">
<div class="message"><p>Currently there are no deferred actions</p></div>
</div>
<%= render :partial => "todos/item", :collection => @tickles, :locals => { :parent_container_type => 'tickler' } %>
</div><!-- [end:items] -->
</div><!-- [end:tickler] -->
</div><!-- End of display_box -->
<div id="input_box">
<%= render :partial => "shared/add_new_item_form" %>
<%= render "sidebar/sidebar" %>
</div><!-- End of input box -->

View file

@ -8,7 +8,7 @@
<div id="t_empty-nd" style="display:<%= @todos.empty? ? 'block' : 'none'%>;">
<div class="message"><p>Currently there are no actions tagged with <%= @tag %></p></div>
</div>
<%= render :partial => "todo/item", :collection => @todos, :locals => { :parent_container_type => "tag" } %>
<%= render :partial => "todos/item", :collection => @todos, :locals => { :parent_container_type => "tag" } %>
</div><!-- [end:items] -->
</div><!-- [end:t-->

View file

@ -3,7 +3,7 @@ if @saved
if @item.completed?
# Don't try to insert contents into a non-existent container!
unless @user.prefs.hide_completed_actions?
page.insert_html :top, "completed", :partial => 'todo/item', :locals => { :parent_container_type => "completed" }
page.insert_html :top, "completed", :partial => 'todos/item', :locals => { :parent_container_type => "completed" }
page.visual_effect :highlight, dom_id(@item, 'line'), {'startcolor' => "'#99ff99'"}
page[empty_container_msg_div_id].show if @down_count == 0 && !empty_container_msg_div_id.nil?
page.show 'tickler-empty-nd' if source_view_is(:project) && @deferred_count == 0
@ -14,7 +14,7 @@ if @saved
end
else
page.call "todoItems.ensureVisibleWithEffectAppear", item_container_id
page.insert_html :bottom, item_container_id, :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.insert_html :bottom, item_container_id, :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@item, 'line'), {'startcolor' => "'#99ff99'"}
page.show "empty-d" if @completed_count == 0
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil? # If we've checked something as undone, uncompleted items can't be empty

View file

@ -18,7 +18,7 @@ if @saved
if source_view_is(:todo) && @item.active?
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@item.context_id}"
page.call "todoItems.expandNextActionListingByContext", "c#{@item.context_id}items", true
page.insert_html :bottom, "c#{@item.context_id}items", :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.insert_html :bottom, "c#{@item.context_id}items", :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
end
page.replace_html("badge_count", @remaining_undone_in_context) if source_view_is :context
page.delay(0.5) do
@ -29,7 +29,7 @@ if @saved
end
end
else
page.replace dom_id(@item), :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.replace dom_id(@item), :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@item), :duration => 3
end
elsif source_view_is :project
@ -40,22 +40,22 @@ if @saved
elsif @item.deferred?
page[@item].remove
page.show("p#{@original_item_project_id}empty-nd") if (@remaining_undone_in_project == 0)
page.insert_html :bottom, "tickler", :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.insert_html :bottom, "tickler", :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page['tickler-empty-nd'].hide
page.replace_html "badge_count", @remaining_undone_in_project
elsif @item_was_activated_from_deferred_state
page[@item].remove
page['tickler-empty-nd'].show if (@deferred_count == 0)
page.insert_html :bottom, "p#{@item.project_id}", :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.insert_html :bottom, "p#{@item.project_id}", :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page["p#{@item.project_id}empty-nd"].hide
page.replace_html "badge_count", @remaining_undone_in_project
else
page.replace dom_id(@item), :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.replace dom_id(@item), :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@item), :duration => 3
end
elsif source_view_is :deferred
if @item.deferred?
page.replace dom_id(@item), :partial => 'todo/item', :locals => { :parent_container_type => parent_container_type }
page.replace dom_id(@item), :partial => 'todos/item', :locals => { :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@item), :duration => 3
else
page[@item].remove

View file

@ -14,9 +14,7 @@ ActionController::Routing::Routes.draw do |map|
# instead of a file named 'wsdl'
#map.connect ':controller/service.wsdl', :action => 'wsdl'
# Index Route
map.connect '', :controller => 'todo', :action => 'index'
# Admin Routes
map.connect 'admin', :controller => 'admin', :action => 'index'
map.connect 'admin/destroy/:id', :controller => 'admin', :action => 'destroy', :requirements => {:id => /\d+/}
@ -31,8 +29,15 @@ ActionController::Routing::Routes.draw do |map|
map.connect 'signup', :controller => 'login', :action => 'signup'
# ToDo Routes
map.connect 'done', :controller => 'todo', :action => 'completed'
map.connect 'tickler', :controller => 'todo', :action => 'tickler'
map.resources :todos, :member => {:toggle_check => :post}
map.with_options :controller => "todos" do |todos|
todos.home '', :action => "index"
todos.tickler 'tickler', :action => "list_deferred"
todos.check_tickler 'check_tickler', :action => "check_tickler"
todos.done 'done', :action => "completed"
todos.done_archive 'done/archive', :action => "completed_archive"
todos.tag '/todos/tag/:name', :action => "tag"
end
# Context Routes
map.resources :contexts, :collection => {:order => :post}

View file

@ -21,7 +21,7 @@ class AdminControllerTest < Test::Unit::TestCase
def test_get_index_by_nonadmin
@request.session['user_id'] = users(:other_user).id
get :index
assert_redirected_to :controller => 'todo', :action => 'index'
assert_redirected_to home_path
end
def test_get_index_by_admin

View file

@ -44,7 +44,7 @@ class LoginControllerTest < Test::Unit::TestCase
assert_equal user.login, "jane"
assert user.is_admin == false || user.is_admin == 0
assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash[:notice]
assert_redirected_to :controller => 'todo', :action => 'index'
assert_redirected_to home_url
end
def test_login_with_no_users_redirects_to_signup
@ -88,14 +88,14 @@ class LoginControllerTest < Test::Unit::TestCase
assert admin.is_admin
newbie = create('newbie', 'newbiepass')
assert_equal "Signup successful for user newbie.", flash[:notice]
assert_redirected_to :controller => 'todo', :action => 'index'
assert_redirected_to home_url
assert_valid newbie
get :logout # logout the admin user
assert_equal newbie.login, "newbie"
assert newbie.is_admin == false || newbie.is_admin == 0
assert_not_nil newbie.preference # have user preferences been created?
user = login('newbie', 'newbiepass', 'on') # log in the new user
assert_redirected_to :controller => 'todo', :action => 'index'
assert_redirected_to home_url
assert_equal 'newbie', user.login
assert user.is_admin == false || user.is_admin == 0
assert_equal User.count, @num_users_in_fixture + 1

View file

@ -1,14 +1,14 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'todo_controller'
require 'todos_controller'
# Re-raise errors caught by the controller.
class TodoController; def rescue_action(e) raise e end; end
class TodosController; def rescue_action(e) raise e end; end
class TodoControllerTest < Test::Unit::TestCase
class TodosControllerTest < Test::Unit::TestCase
fixtures :users, :preferences, :projects, :contexts, :todos, :tags, :taggings
def setup
@controller = TodoController.new
@controller = TodosController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end

View file

@ -37,7 +37,7 @@ class StoriesTest < ActionController::IntegrationTest
assert_response :redirect
follow_redirect!
assert_response :success
assert_template "todo/index"
assert_template "todos/index"
end
def goes_to_login
@ -63,7 +63,7 @@ class StoriesTest < ActionController::IntegrationTest
assert_response :redirect
follow_redirect!
assert_response :success
assert_template "todo/index"
assert_template "todos/index"
end
end

View file

@ -0,0 +1,4 @@
setup :fixtures => :all
include_partial 'login/login', :username => 'admin', :password => 'abracadabra'
open "/tickler/"
assert_element_present "todo_15"