get destroying of actions working

This commit is contained in:
Reinier Balt 2010-12-20 18:20:37 +01:00
parent e13e946295
commit 33f68df154
18 changed files with 246 additions and 96 deletions

View file

@ -112,17 +112,17 @@ class RecurringTodosController < ApplicationController
end
if @saved
@message = "The recurring todo was saved"
@status_message = "The recurring todo was saved"
@todo_saved = create_todo_from_recurring_todo(@recurring_todo).nil? == false
if @todo_saved
@message += " / created a new todo"
@status_message += " / created a new todo"
else
@message += " / did not create todo"
@status_message += " / did not create todo"
end
@down_count = current_user.recurring_todos.active.count
@new_recurring_todo = RecurringTodo.new
else
@message = "Error saving recurring todo"
@status_message = "Error saving recurring todo"
end
respond_to do |format|

View file

@ -118,6 +118,11 @@ class TodosController < ApplicationController
@initial_context_name = params['default_context_name']
@initial_project_name = params['default_project_name']
@default_tags = @todo.project.default_tags unless @todo.project.nil?
@status_message = 'Added new next action'
@status_message += ' to tickler' if @todo.deferred?
@status_message += ' in pending state' if @todo.pending?
@status_message = 'Added new project / ' + status_message if @new_project_created
@status_message = 'Added new context / ' + status_message if @new_context_created
render :action => 'create'
end
format.xml do
@ -295,6 +300,7 @@ class TodosController < ApplicationController
respond_to do |format|
format.js
format.xml { render :xml => @todo.to_xml( :except => :user_id ) }
format.html { redirect_to request.referrer}
end
end
@ -452,6 +458,7 @@ class TodosController < ApplicationController
end
def destroy
@source_view = params['_source_view'] || 'todo'
@todo = get_todo_from_params
@original_item_due = @todo.due
@context_id = @todo.context_id

View file

@ -32,15 +32,13 @@ module TodosHelper
:title => t('todos.edit_action_with_description', :description => @todo.description))
end
def remote_delete_menu_item(parameters, todo)
return link_to_remote(
def remote_delete_menu_item(todo)
return link_to(
image_tag("delete_off.png", :mouseover => "delete_on.png", :alt => t('todos.delete'), :align => "absmiddle")+" "+t('todos.delete'),
:url => {:controller => 'todos', :action => 'destroy', :id => todo.id},
:method => 'delete',
:with => "'#{parameters}'",
:before => todo_start_waiting_js(todo),
:complete => todo_stop_waiting_js(todo),
:confirm => t('todos.confirm_delete', :description => todo.description))
{:controller => 'todos', :action => 'destroy', :id => todo.id},
:class => "icon_delete_item",
:id => "delete_#{dom_id(todo)}",
:title => t('todos.confirm_delete', :description => todo.description));
end
def remote_defer_menu_item(days, todo)
@ -264,11 +262,17 @@ module TodosHelper
def empty_container_msg_div_id
todo = @todo || @successor
return "" unless todo # empty id if no todo or successor given
return "tickler-empty-nd" if source_view_is_one_of(:project, :tag) && todo.deferred?
return "tickler-empty-nd" if source_view_is_one_of(:project, :tag, :deferred) && todo.deferred?
return "p#{todo.project_id}empty-nd" if source_view_is :project
return "c#{todo.context_id}empty-nd"
end
def todo_container_is_empty
default_container_empty = ( @down_count == 0 )
deferred_container_empty = ( @todo.deferred? && @deferred_count == 0)
return default_container_empty || deferred_container_empty
end
def default_contexts_for_autocomplete
projects = current_user.projects.find(:all, :conditions => ['default_context_id is not null'])
Hash[*projects.map{ |p| [p.name, p.default_context.name] }.flatten].to_json

View file

@ -1,4 +1,5 @@
<% if @saved -%>
TracksPages.page_notify('notice', "<%=@status_message%>", 5);
RecurringTodosPage.toggle_overlay();
add_recurring_todo_to_active_container();
replace_form_with_empty_form();

View file

@ -11,17 +11,15 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
<div id="<%= dom_id(todo, 'line') %>" class="item-show">
<%= remote_star_icon %>
<%= remote_toggle_checkbox unless source_view_is :deferred %>
<% unless suppress_edit_button %>
<%= remote_edit_button %>
<% end %>
<%= remote_edit_button unless suppress_edit_button %>
<ul class="sf-menu sf-item-menu">
<li style="z-index:<%=@z_index_counter%>"><%= image_tag "downarrow.png", :alt=> "" %>
<ul id="ul<%= dom_id(todo) %>">
<li><%= remote_delete_menu_item(parameters, todo) %></li>
<% unless todo.completed? || todo.deferred? %>
<li><%= remote_delete_menu_item(todo) %></li>
<% unless todo.completed? || todo.deferred? -%>
<li><%= remote_defer_menu_item(1, todo) %></li>
<li><%= remote_defer_menu_item(7, todo) %></li>
<% end %>
<% end -%>
<li><%= remote_promote_to_project_menu_item(todo) %></li>
</ul>
</li>
@ -30,7 +28,6 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
<%= grip_span %>
<%= date_span -%>
<span class="todo.descr"><%= h todo.description %></span>
<% #= successors_span %>
<%= image_tag_for_recurring_todo(todo) if @todo.from_recurring_todo? %>
<%= tag_list %>
<%= deferred_due_date %>

View file

@ -1,9 +1,6 @@
<%
suppress_button ||= false
%>
<%= link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_successors', :title => 'Show successors'}) unless suppress_button %>
<%= link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_successors', :title => 'Show successors'}) %>
<div class="todo_successors" id="<%= dom_id(item, 'successors') %>" style=<%= suppress_button ? "display:display" : "display:none" %> >
<div class="todo_successors" id="<%= dom_id(item, 'successors') %>">
<%= render :partial => "todos/successor",
:collection => item.pending_successors,
:locals => { :todo => item,

View file

@ -1,5 +1,5 @@
<% if @saved -%>
set_notification();
TracksPages.page_notify('notice', "<%=@status_message%>", 5);
hide_empty_message();
TracksPages.hide_errors();
TracksPages.set_page_badge(<%= @down_count %>);
@ -16,17 +16,6 @@
TracksPages.show_errors(html_for_error_messages());
<% end -%>
function set_notification() {
<%-
status_message = 'Added new next action'
status_message += ' to tickler' if @todo.deferred?
status_message += ' in pending state' if @todo.pending?
status_message = 'Added new project / ' + status_message if @new_project_created
status_message = 'Added new context / ' + status_message if @new_context_created
-%>
TracksPages.page_notify('notice', "<%=status_message%>", 5);
}
function hide_empty_message() {
<% if @todo %>
$('#<%=empty_container_msg_div_id%>').hide();

View file

@ -16,7 +16,8 @@
<% end -%>
<% if @saved
# the following functions assume a todo is saved or not nil, so leave them out in case of an error
# the following functions assume a todo is saved or at least not nil,
# so leave them out in case of an error
-%>
function set_notification() {

View file

@ -1,36 +1,75 @@
if @saved
page[@todo].remove
page.show "empty_"+@original_item_due_id if @old_due_empty
page['badge_count'].replace_html @down_count
<%- if @saved -%>
TracksPages.page_notify('notice', '<%= escape_javascript("The action was deleted succesfully") %>', 5);
TracksPages.set_page_badge(<%=@down_count%>);
remove_todo_from_page();
show_new_todo_if_todo_was_recurring();
activate_pending_todos();
show_empty_messages();
<%- else -%>
TracksPages.page_notify('error', "<%= t('todos.error_deleting_item', :description => @todo.description) %>", 8);
<%- end -%>
# remove context if empty
page.visual_effect(:fade, "c#{@todo.context_id}", :duration => 0.4) if (@remaining_in_context == 0)
<% if @saved
# do not send the js in case of an error
-%>
# show message if there are no actions
page[empty_container_msg_div_id].show if !empty_container_msg_div_id.nil? && @down_count == 0
page['tickler-empty-nd'].show if source_view_is(:deferred) && @down_count == 0
function show_empty_messages() {
<% if @old_due_empty -%>
$('#empty_<%=@original_item_due_id%>').slideDown(1000);
<% end -%>
# show new todo if the completed todo was recurring
if @todo.from_recurring_todo?
unless @new_recurring_todo.nil? || @new_recurring_todo.deferred?
page.call "todoItems.ensureVisibleWithEffectAppear", item_container_id(@new_recurring_todo)
page.insert_html :bottom, item_container_id(@new_recurring_todo), :partial => 'todos/todo', :locals => { :todo => @new_recurring_todo, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@new_recurring_todo, 'line'), {'startcolor' => "'#99ff99'"}
page.notify :notice, t('todos.recurring_action_deleted'), 6.0
else
if @todo.recurring_todo.todos.active.count == 0
page.notify :notice, t('todos.completed_recurrence_completed'), 6.0 if @new_recurring_todo.nil?
end
end
end
<% if empty_container_msg_div_id && todo_container_is_empty -%>
$('#<%=empty_container_msg_div_id%>').slideDown(1000);
<% end -%>
}
# Activate pending todos that are successors of the deleted
@pending_to_activate.each do |t|
logger.debug "#300: Removing #{t.description} from pending block and adding it to active"
page[t].remove if source_view_is(:project) or source_view_is(:tag)
page.insert_html :bottom, item_container_id(t), :partial => 'todos/todo', :locals => { :todo => t, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(t, 'line'), {'startcolor' => "'#99ff99'", :duration => 2}
end
else
page.notify :error, t('todos.error_deleting_item', :description => @todo.description), 8.0
end
function remove_todo_from_page() {
<% if (@remaining_in_context == 0)
# remove context with deleted todo
-%>
$('#c<%=@todo.context_id%>').fadeOut(1000, function() {
$('#<%=dom_id(@todo)%>').remove();
});
<% else
# remove only the todo
-%>
$('#<%=dom_id(@todo)%>').slideUp(1000, function() {
$('#<%=dom_id(@todo)%>').remove();
});
<% end -%>
}
function show_new_todo_if_todo_was_recurring() {
<% if @todo.from_recurring_todo? -%>
<% unless @new_recurring_todo.nil? || @new_recurring_todo.deferred? -%>
TodoItemsContainer.ensureVisibleWithEffectAppear("<%=item_container_id(@new_recurring_todo)%>");
$('#<%=item_container_id(@new_recurring_todo)%>').append(html_for_new_recurring_todo());
$('#<%= dom_id(@new_recurring_todo, 'line')%>').effect('highlight', {}, 2000 );
TracksPages.page_notify('notice', "Action was deleted. Because this action is recurring, a new action was added", 5);
<% else -%>
<% if @todo.recurring_todo.todos.active.count == 0 && @new_recurring_todo.nil? -%>
TracksPages.page_notify('notice', "There is no next action after the recurring action you just deleted. The recurrence is completed", 5);
<% end -%>
<% end -%>
<% end -%>
}
function activate_pending_todos() {
<% # Activate pending todos that are successors of the deleted -%>
<% @pending_to_activate.each do |t| -%>
<% if source_view_is(:project) or source_view_is(:tag) %>
$('#<%=dom_id(t)%>').remove();
<% end -%>
$('#<%=item_container_id(t)%>').append("<%=escape_javascript(render(:partial => 'todos/todo', :locals => { :todo => t, :parent_container_type => parent_container_type }))%>");
$('#<%= dom_id(t, 'line')%>').effect('highlight', {}, 2000 );
<% end -%>
}
function html_for_new_recurring_todo() {
return "<%= @saved && @new_recurring_todo ? escape_javascript(render(:partial => 'todos/todo', :locals => { :todo => @new_recurring_todo, :parent_container_type => parent_container_type })) : "" %>";
}
<% end
# if @saved
-%>
>>>>>>> get destroying of actions working

View file

@ -1,3 +1,5 @@
<% if @saved -%>
$('div#line_todo_<%= @todo.id %> a.star_item img').toggleClass('starred_todo').toggleClass('unstarred_todo');
<% else -%>
TracksPages.page_notify('error', "Could not toggle the star of this todo", 5);
<% end -%>

19
features/calendar.feature Normal file
View file

@ -0,0 +1,19 @@
Feature: dependencies
As a Tracks user
In order to keep overview of my due todos
I want to manage due todos in a calendar view
Background:
Given the following user record
| login | password | is_admin |
| testuser | secret | false |
And I have logged in as "testuser" with password "secret"
Scenario: Setting due date of a todo will show it in the calendar
Given this is a pending scenario
Scenario: Clearing the due date of a todo will remove it from the calendar
Given this is a pending scenario
Scenario: Changing due date of a todo will move it in the calendar
Given this is a pending scenario

View file

@ -9,7 +9,7 @@ Feature: dependencies
| testuser | secret | false |
And I have logged in as "testuser" with password "secret"
@selenium
@selenium @wip
Scenario: Adding dependency to dependency
Given I have a project "dependencies" with 3 todos
And "Todo 2" depends on "Todo 1"
@ -35,3 +35,6 @@ Feature: dependencies
Then the dependencies of "test me" should include "test,1, 2,3"
When I edit the dependency of "test me" to '"test,1, 2,3" <"@pc"; "dependencies">,"test,1, 2,3" <"@pc"; "dependencies">'
Then there should not be an error
Scenario: Deleting a predecessor will activate successors
Given this scenario is pending

View file

@ -0,0 +1,55 @@
Feature: Edit a next action from every page
In order to manage a next action
As a Tracks user
I want to to be able to change the next action from every page
Background:
Given the following user record
| login | password | is_admin |
| testuser | secret | false |
And I have logged in as "testuser" with password "secret"
Scenario: I can toggle the star of a todo
Given this is a pending scenario
Scenario: I can delete a todo
Given this is a pending scenario
Scenario: Deleting the last todo in context will hide context
Given this is a pending scenario
Scenario: Deleting the last todo in container will show empty message
Given this is a pending scenario
Scenario: I can mark a todo complete
Given this is a pending scenario
Scenario: I can mark a completed todo active
Given this is a pending scenario
Scenario: I can edit a todo to move it to another context
Given this is a pending scenario
Scenario: I can edit a todo to move it to another project
Given this is a pending scenario
Scenario: I can edit a todo to move it to the tickler
Given this is a pending scenario
Scenario: I can defer a todo
Given this is a pending scenario
Scenario: I can make a project from a todo
Given this is a pending scenario
Scenario: I can show the notes of a todo
Given this is a pending scenario
Scenario: I can tag a todo
Given this is a pending scenario
Scenario: Clicking a tag of a todo will go to that tag page
Given this is a pending scenario
Scenario: I can edit the tags of a todo
Given this is a pending scenario

View file

@ -23,7 +23,7 @@ Feature: Manage users
Then I should be on the manage users page
And I should see "new.user"
@selenium
@selenium @wip
Scenario: Delete account from users page
When I go to the manage users page
And I delete the user "testuser"

View file

@ -90,3 +90,6 @@ Feature: Edit a project
And I add a note "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG" to the project
Then I should not see "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG"
And I should see "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456"
Scenario: Cancelling editing a project will restore project settings
Given this scenario is pending

View file

@ -61,3 +61,12 @@ Feature: Manage recurring todos
When I mark the pattern "I'm done" as active
Then the pattern "I'm done" should be in the state list "active"
And the state list "completed" should be empty
Scenario: Following the recurring todo link of a todo takes me to the recurring todos page
Given this is a pending scenario
Scenario: Deleting a recurring todo with ending pattern will show message
Given this is a pending scenario
Scenario: Deleting a recurring todo with active pattern will show new todo
Given this is a pending scenario

View file

@ -119,6 +119,24 @@ Feature: Add new next action from every page
| visit | context page for "test context" | see | 2 | 3 |
| visit | tag page for "starred" | not see | 0 | 3 |
Scenario: Adding a todo to another project does not show the todo
Given this is a pending scenario
Scenario: Adding a todo to a hidden project does not show the todo
Given this is a pending scenario
Scenario: Adding a todo with a new context shows the new context
Given this is a pending scenario
Scenario: Adding a todo to a hidden context does not show the todo
Given this is a pending scenario
Scenario: Adding a todo to an empty container hides the empty message
Given this is a pending scenario
Scenario: Adding a dependency to a todo updated the successor
Given this is a pending scenario
@selenium
Scenario: I need to fill in at least one description and a context
When I go to the home page

View file

@ -331,15 +331,14 @@ var TodoItems = {
/* set behavior for star icon */
$(".item-container a.star_item").live('click', function (ev){
$.post(this.href, {
_method: 'put'
}, null, 'script');
put_with_ajax_and_block_element(this.href, $(this));
return false;
});
/* set behavior for toggle checkboxes for Recurring Todos */
$(".item-container input.item-checkbox").live('click', function(ev){
put_with_ajax_and_block_element(this.value, $(this));
return false;
});
/* set behavior for edit icon */
@ -347,6 +346,15 @@ var TodoItems = {
get_with_ajax_and_block_element(this.href, $(this).parents(".item-container"));
return false;
});
/* delete button to delete a project from the list
* :with => "'#{parameters}'",*/
$('.item-container a.icon_delete_item').live('click', function(evt){
if(confirm(this.title)){
delete_with_ajax_and_block_element(this.href, $(this).parents('.project'));
}
return false;
});
}
}
@ -383,7 +391,6 @@ var ProjectListPage = {
return(value);
},
setup_behavior: function() {
/* in-place edit of project name */
$('h2#project_name').editable(ProjectListPage.save_project_name, {
style: 'padding:0px',
@ -726,10 +733,11 @@ function generic_get_script_for_list(element, getter, param){
}
function default_ajax_options_for_submit(ajax_type, element_to_block) {
return {
options = {
type: ajax_type,
async: true,
context: element_to_block,
data: "_source_view=" + encodeURIComponent( SOURCE_VIEW ),
beforeSend: function() {
$(this).block({
message: null
@ -743,6 +751,9 @@ function default_ajax_options_for_submit(ajax_type, element_to_block) {
TracksPages.page_notify('error', 'There was an error retrieving from server: '+status, 8);
}
}
if(typeof(TAG_NAME) !== 'undefined')
options.data += "&_tag_name="+ encodeURIComponent (TAG_NAME);
return options;
}
function default_ajax_options_for_scripts(ajax_type, the_url, element_to_block) {
@ -766,9 +777,7 @@ function post_with_ajax_and_block_element(the_url, element_to_block) {
function put_with_ajax_and_block_element(the_url, element_to_block) {
options = default_ajax_options_for_scripts('POST', the_url, element_to_block);
options.data = '_method=put';
if(typeof(TAG_NAME) !== 'undefined')
options.data += "&_tag_name="+ encodeURIComponent (TAG_NAME);
options.data += '&_method=put';
$.ajax(options);
}
@ -793,10 +802,7 @@ $(document).ajaxSend(function(event, request, settings) {
});
function setup_periodic_check(url_for_check, interval_in_sec, method) {
ajaxMethod = "GET"
if (method) {
ajaxMethod = method;
}
ajaxMethod = (method ? method : "GET");
function check_remote() {
$.ajax({