diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index 9bc7ea29..db025cfa 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -158,8 +158,8 @@ class ContextsController < ApplicationController @context = current_user.contexts.find(params[:id]) @page_title = t('contexts.completed_tasks_title', :context_name => @context.name) - @done_today, @done_this_week, @done_this_month = DoneTodos.done_todos_for_container(@context) - @count = @done_today.size + @done_this_week.size + @done_this_month.size + @done_today, @done_rest_of_week, @done_rest_of_month = DoneTodos.done_todos_for_container(@context) + @count = @done_today.size + @done_rest_of_week.size + @done_rest_of_month.size render :template => 'todos/done' end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 8996c300..ee521a95 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -307,8 +307,8 @@ class ProjectsController < ApplicationController @project = current_user.projects.find(params[:id]) @page_title = t('projects.completed_tasks_title', :project_name => @project.name) - @done_today, @done_this_week, @done_this_month = DoneTodos.done_todos_for_container(@project) - @count = @done_today.size + @done_this_week.size + @done_this_month.size + @done_today, @done_rest_of_week, @done_rest_of_month = DoneTodos.done_todos_for_container(@project) + @count = @done_today.size + @done_rest_of_week.size + @done_rest_of_month.size render :template => 'todos/done' end diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index db0239f2..1c5aa43a 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -329,13 +329,16 @@ class TodosController < ApplicationController def toggle_check @todo = current_user.todos.find(params['id']) @source_view = params['_source_view'] || 'todo' + @original_item_due = @todo.due @original_item_was_deferred = @todo.deferred? @original_item_was_pending = @todo.pending? @original_item_was_hidden = @todo.hidden? @original_item_context_id = @todo.context_id @original_item_project_id = @todo.project_id + @original_completed_period = DoneTodos.completed_period(@todo.completed_at) @todo_was_completed_from_deferred_or_blocked_state = @original_item_was_deferred || @original_item_was_pending + @saved = @todo.toggle_completion! @todo_was_blocked_from_completed_state = @todo.pending? # since we toggled_completion the previous state was completed @@ -556,8 +559,8 @@ class TodosController < ApplicationController @source_view = 'done' @page_title = t('todos.completed_tasks_title') - @done_today, @done_this_week, @done_this_month = DoneTodos.done_todos_for_container(current_user) - @count = @done_today.size + @done_this_week.size + @done_this_month.size + @done_today, @done_rest_of_week, @done_rest_of_month = DoneTodos.done_todos_for_container(current_user) + @count = @done_today.size + @done_rest_of_week.size + @done_rest_of_month.size respond_to do |format| format.html @@ -697,9 +700,9 @@ class TodosController < ApplicationController completed_todos = current_user.todos.completed.with_tag(@tag.id) @done_today = get_done_today(completed_todos) - @done_this_week = get_done_this_week(completed_todos) - @done_this_month = get_done_this_month(completed_todos) - @count = @done_today.size + @done_this_week.size + @done_this_month.size + @done_rest_of_week = get_done_rest_of_week(completed_todos) + @done_rest_of_month = get_done_rest_of_month(completed_todos) + @count = @done_today.size + @done_rest_of_week.size + @done_rest_of_month.size render :template => 'todos/done' end @@ -1009,9 +1012,8 @@ class TodosController < ApplicationController } from.tag { tag = Tag.where(:name => params['_tag_name']).first - if tag.nil? - tag = Tag.new(:name => params['tag']) - end + tag = Tag.new(:name => params['tag']) if tag.nil? + @remaining_deferred_or_pending_count = current_user.todos.with_tag(tag.id).deferred_or_blocked.count @remaining_in_context = current_user.contexts.find(context_id).todos.active.not_hidden.with_tag(tag.id).count @target_context_count = current_user.contexts.find(@todo.context_id).todos.active.not_hidden.with_tag(tag.id).count @@ -1048,9 +1050,12 @@ class TodosController < ApplicationController end @target_context_count = actions_in_target.count } + from.done { + @remaining_in_context = DoneTodos.remaining_in_container(current_user, @original_completed_period) + } end - @remaining_in_context = current_user.contexts.find(context_id).todos(true).active.not_hidden.count if !@remaining_in_context - @target_context_count = current_user.contexts.find(@todo.context_id).todos(true).active.not_hidden.count if !@target_context_count + @remaining_in_context = current_user.contexts.find(context_id).todos(true).active.not_hidden.count if @remaining_in_context.nil? + @target_context_count = current_user.contexts.find(@todo.context_id).todos(true).active.not_hidden.count if !@target_context_count.nil? end def determine_completed_count @@ -1334,14 +1339,14 @@ class TodosController < ApplicationController end # all completed todos [begin_of_week, start_of_today] - def get_done_this_week(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + def get_done_rest_of_week(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) start_of_this_week = Time.zone.now.beginning_of_week start_of_this_day = Time.zone.now.beginning_of_day completed_todos.completed_before(start_of_this_day).completed_after(start_of_this_week).all(includes) end # all completed todos [begin_of_month, begin_of_week] - def get_done_this_month(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + def get_done_rest_of_month(completed_todos, includes = {:include => Todo::DEFAULT_INCLUDES}) start_of_this_month = Time.zone.now.beginning_of_month start_of_this_week = Time.zone.now.beginning_of_week completed_todos.completed_before(start_of_this_week).completed_after(start_of_this_month).all(includes) diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 5e8404a7..b21a01b8 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -44,6 +44,19 @@ module TodosHelper :locals => {:settings => settings.reverse_merge!(default_collection_settings)} end + def show_completed_todos_for(period, collection) + settings = { + :parent_container_type => "completed", + :container_name => "completed_#{period}", + :title => t("todos.completed_#{period}"), + :show_empty_containers => true + } + + render :partial => "todos/collection", + :object => collection, + :locals => { :settings => settings} + end + def show_hidden_todos(hidden_todos, settings={}) settings[:container_name] = "hidden" @@ -410,7 +423,7 @@ module TodosHelper (@remaining_in_context == 0 && @tag_was_removed) || (@remaining_in_context == 0 && @todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden)) if source_view_is(:tag) - return false if source_view_is_one_of(:project, :calendar) + return false if source_view_is_one_of(:project, :calendar, :done) return (@remaining_in_context == 0) && !source_view_is(:context) end @@ -531,6 +544,7 @@ module TodosHelper container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed? } page.todo { container_id = "c#{@original_item_context_id}-empty-d" if @remaining_in_context == 0 } + page.done { container_id = "completed_#{@original_completed_period}_container-empty-d" if @remaining_in_context == 0 } end return container_id.blank? ? "" : "$(\"##{container_id}\").slideDown(100);".html_safe end diff --git a/app/views/todos/done.html.erb b/app/views/todos/done.html.erb index ce6875a6..c5b5b0d9 100644 --- a/app/views/todos/done.html.erb +++ b/app/views/todos/done.html.erb @@ -1,31 +1,13 @@
-
-

<%= t('todos.completed_today') %>

- <% if @done_today.empty? -%> -

<%= t('todos.no_completed_actions') %>

- <% else -%> - <%= render :partial => "todos/todo", :collection => @done_today, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> - <% end -%> -
- -
-

<%= t('todos.completed_rest_of_week') %>

- <% if @done_this_week.empty? -%> -

<%= t('todos.no_completed_actions') %>

- <% else -%> - <%= render :partial => "todos/todo", :collection => @done_this_week, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> - <% end -%> -
- -
-

<%= t('todos.completed_rest_of_month') %>

- <% if @done_this_month.empty? -%> -

<%= t('todos.no_completed_actions') %>

- <% else -%> - <%= render :partial => "todos/todo", :collection => @done_this_month, :locals => { :parent_container_type => "completed", :suppress_context => false, :suppress_project => false } %> - <% end -%> -
-

<%= raw t('todos.see_all_completed', :link => link_to(t("todos.all_completed_here"), determine_all_done_path)) %>

+ <%= show_completed_todos_for("today", @done_today) %> + <%= show_completed_todos_for("rest_of_week", @done_rest_of_week) %> + <%= show_completed_todos_for("rest_of_month", @done_rest_of_month) %> + +

+ <%= raw t('todos.see_all_completed', + :link => link_to(t("todos.all_completed_here"), determine_all_done_path)) + %> +

diff --git a/config/locales/en.yml b/config/locales/en.yml index 82b8162d..defa2eea 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -431,6 +431,9 @@ en: not_done: Currently there are no incomplete actions project: Currently there are no incomplete actions in this project context: Currently there are no incomplete actions in this context + completed_today: No actions were completed today + completed_rest_of_week: No actions were completed in the rest of this week + completed_rest_of_month: No actions were completed in the rest of this month actions: completed: Completed actions home_completed: Completed actions @@ -443,6 +446,9 @@ en: project_completed: Completed actions in this project context_completed: Completed actions in this context tag_hidden: "Hidden actions tagged with '%{param}'" + completed_today: Completed today + completed_rest_of_week: Completed in the rest of this week + completed_rest_of_month: Completed in the rest of this month show_from: Show from error_starring_recurring: "Could not toggle the star of recurring todo \'%{description}\'" recurring_action_deleted: Action was deleted. Because this action is recurring, a new action was added @@ -556,10 +562,8 @@ en: one: One tickler item is now due - refresh the page to see it. other: "%{count} tickler items are now due - refresh the page to see them." action_marked_complete: "The action '%{description}' was marked as %{completed}" - completed_today: Completed today added_new_next_action_plural: Added new next actions new_related_todo_not_created_short: did not create todo - completed_rest_of_week: Completed in the rest of this week error_starring: "Could not toggle the star of this todo '%{description}'" calendar: get_in_ical_format: Get this calendar in iCal format @@ -647,7 +651,6 @@ en: yearly: Yearly added_dependency: Added %{dependency} as dependency. all_completed_tagged_page_title: TRACKS::All completed tasks with tag %{tag_name} - completed_rest_of_month: Completed in the rest of this month recurrence_completed: There is no next action after the recurring action you just finished. The recurrence is completed error_toggle_complete: Could not mark this todo complete in_pending_state: in pending state diff --git a/features/step_definitions/container_steps.rb b/features/step_definitions/container_steps.rb index 02e80363..449ab792 100644 --- a/features/step_definitions/container_steps.rb +++ b/features/step_definitions/container_steps.rb @@ -122,20 +122,17 @@ end ####### Completed ####### -Then /^I should see "([^"]*)" in the completed container$/ do |todo_description| +Then /^I should (not see|see) "([^"]*)" in the (completed|done today|done this week|done this month) container$/ do |visible, todo_description, container| todo = @current_user.todos.where(:description => todo_description).first todo.should_not be_nil - xpath = "//div[@id='completed_container']//div[@id='line_todo_#{todo.id}']" - page.should have_xpath(xpath) -end + id = 'completed_container' if container == 'completed' + id = 'completed_today_container' if container == 'done today' + id = 'completed_rest_of_week_container' if container == 'done this week' + id = 'completed_rest_of_month_container' if container == 'done this month' -Then /^I should not see "([^"]*)" in the completed container$/ do |todo_description| - todo = @current_user.todos.where(:description => todo_description).first - todo.should_not be_nil - - xpath = "//div[@id='completed_container']//div[@id='line_todo_#{todo.id}']" - page.should_not have_xpath(xpath) + xpath = "//div[@id='#{id}']//div[@id='line_todo_#{todo.id}']" + page.send( visible=='see' ? :should : :should_not, have_xpath(xpath)) end ####### Hidden ####### @@ -181,4 +178,22 @@ Then /^I should not see "([^"]*)" in the completed recurring todos container$/ d else step "I should not see \"#{repeat_pattern}\"" end +end + +####### Empty message patterns ####### + +Then /^I should (see|not see) empty message for (done today|done this week|done this month|completed todos|deferred todos|todos) (of done actions|of context|of project|of home|of tag)/ do |visible, state, type| + css = "error: wrong state" + css = "div#c#{@context.id}-empty-d" if state == "todos" && type == "of context" + css = "div#p#{@project.id}-empty-d" if state == "todos" && type == "of project" + css = "div#no_todos_in_view" if state == "todos" && (type == "of home" || type == "of tag") + css = "div#completed_today_container" if state == "done today" + css = "div#completed_rest_of_week_container" if state == "done this week" + css = "div#completed_rest_of_month_container" if state == "done this month" + css = "div#completed_container-empty-d" if state == "completed todos" + css = "div#deferred_pending_container-empty-d" if state == "deferred todos" + + elem = find(css) + elem.should_not be_nil + elem.send(visible=="see" ? :should : :should_not, be_visible) end \ No newline at end of file diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb index c6678f91..c13ae0d7 100644 --- a/features/step_definitions/context_steps.rb +++ b/features/step_definitions/context_steps.rb @@ -70,13 +70,4 @@ Then /^he should see that a context named "([^\"]*)" (is|is not) present$/ do |c else page.should_not have_selector("div#context_#{context.id} div.context_description a", :visible => true) if context end -end - -Then /^I should (see|not see) empty message for (todo|completed todo|deferred todo)s of context/ do |visible, state| - css = "error" - css = "div#c#{@context.id}-empty-d" if state == "todo" - css = "div#completed_container-empty-d" if state == "completed todo" - css = "div#deferred_pending_container-empty-d" if state == "deferred todo" - - page.send(visible=="see" ? :should : :should_not, have_css(css, :visible=>true)) end \ No newline at end of file diff --git a/features/step_definitions/generic_steps.rb b/features/step_definitions/generic_steps.rb index 343bc310..91b82213 100644 --- a/features/step_definitions/generic_steps.rb +++ b/features/step_definitions/generic_steps.rb @@ -10,6 +10,11 @@ Given /^I am working on the mobile interface$/ do @mobile_interface = true end +Given /^the date is "(.*?)"$/ do |date| + # remember to tag the scenario with @reset_time to reset this travel + Timecop.travel(date) +end + Then /the badge should show (.*)/ do |number| badge = find("span#badge_count").text.to_i badge.should == number.to_i diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb index 22fee2e7..3cbd1b52 100644 --- a/features/step_definitions/project_steps.rb +++ b/features/step_definitions/project_steps.rb @@ -234,17 +234,6 @@ When /^I cancel adding a note to the project$/ do click_link "neg_edit_form_note" end -Then /^I should (see|not see) empty message for (todos|deferred todos|completed todos) of project/ do |visible, state| - css = "wrong state" - css = "div#p#{@project.id}-empty-d" if state == "todos" - css = "div#deferred_pending_container-empty-d" if state == "deferred todos" - css = "div#completed_container-empty-d" if state == "completed todos" - - elem = find(css) - elem.should_not be_nil - elem.send(visible=="see" ? :should : :should_not, be_visible) -end - Then /^I edit the default tags to "([^"]*)"$/ do |default_tags| edit_project(@project) do fill_in "project[default_tags]", :with => default_tags diff --git a/features/step_definitions/todo_create_steps.rb b/features/step_definitions/todo_create_steps.rb index 4ec71014..382000f1 100644 --- a/features/step_definitions/todo_create_steps.rb +++ b/features/step_definitions/todo_create_steps.rb @@ -162,6 +162,15 @@ Given /^I have a completed todo with description "([^"]*)" in project "([^"]*)" @todo.complete! end +Given(/^I have a completed todo with description "([^"]*)" in context "(.*?)" completed (\d+) days ago$/) do |action_description, context_name, num_of_days| + step "I have a todo \"#{action_description}\" in the context \"#{context_name}\"" + @todo.complete! + @todo.completed_at = Time.zone.now - num_of_days.to_i.days + @todo.save! + @todo.reload +end + + ####### PROJECT WITH TODOS ###### Given /^I have a project "([^"]*)" that has the following (todos|deferred todos)$/ do |project_name, kind_of_todo, todos| diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb index b8c1364b..c89e8cfd 100644 --- a/features/step_definitions/todo_steps.rb +++ b/features/step_definitions/todo_steps.rb @@ -152,19 +152,14 @@ Then /^I should see "([^"]*)" in the completed section of the mobile site$/ do | page.should have_xpath(xpath) end -Then /^I should (see|not see) empty message for (completed todos|todos) of home/ do |visible, kind_of_todo| - elem = find(kind_of_todo=="todos" ? "div#no_todos_in_view" : "div#completed_container-empty-d") - elem.send(visible=="see" ? "should" : "should_not", be_visible) -end - -Then /^I should (see|not see) the empty tickler message$/ do |see| - elem = find("div#no_todos_in_view") - elem.send(see=="see" ? "should" : "should_not", be_visible) -end - Then /^I should (see|not see) the notes of "([^"]*)"$/ do |visible, todo_description| todo = @current_user.todos.where(:description => todo_description).first todo.should_not be_nil page.find("div#notes_todo_#{todo.id}").send(visible=="see" ? "should" : "should_not", be_visible) end + +Then /^I should (see|not see) the empty tickler message$/ do |see| + elem = find("div#no_todos_in_view") + elem.send(see=="see" ? "should" : "should_not", be_visible) +end diff --git a/features/step_definitions/todo_tag_steps.rb b/features/step_definitions/todo_tag_steps.rb index 8cd2c906..e69de29b 100644 --- a/features/step_definitions/todo_tag_steps.rb +++ b/features/step_definitions/todo_tag_steps.rb @@ -1,23 +0,0 @@ -Then /^I should not see empty message for todos of tag$/ do - page.should_not have_css("div#no_todos_in_view", :visible => true) -end - -Then /^I should see empty message for todos of tag$/ do - page.should have_css("div#no_todos_in_view", :visible => true) -end - -Then /^I should not see empty message for completed todos of tag$/ do - page.should_not have_css("div#completed_container-empty-d", :visible=>true) -end - -Then /^I should see empty message for completed todos of tag$/ do - page.should have_css("div#completed_container-empty-d", :visible=>true) -end - -Then /^I should not see empty message for deferred todos of tag$/ do - page.should_not have_css("div#deferred_pending_container-empty-d", :visible=>true) -end - -Then /^I should see empty message for deferred todos of tag$/ do - page.should have_css("div#deferred_pending_container-empty-d", :visible=>true) -end diff --git a/features/support/hooks.rb b/features/support/hooks.rb index 268f94e3..db04f79e 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -6,4 +6,8 @@ end Before('@aruba') do @aruba_timeout_seconds = 5 # print "\nsetting timeout for aruba to #{@aruba_timeout_seconds}\n" +end + +After('@reset_time') do + Timecop.return end \ No newline at end of file diff --git a/features/view_done.feature b/features/view_done.feature index cede43e5..a586b64c 100644 --- a/features/view_done.feature +++ b/features/view_done.feature @@ -35,7 +35,7 @@ Feature: Show done Scenario Outline: I can see all todos completed in the last timeperiod When I go to the Then I should see "todo 1" - And I should see "Completed today" + And I should see "Completed Today" And I should see "Completed in the rest of this week" And I should see "Completed in the rest of this month" @@ -153,6 +153,25 @@ Feature: Show done | all done actions page for project "test project"| "test project" project | | | all done actions page for tag "starred" | home page | in the context container for "@pc" | + @javascript @reset_time + Scenario: Activating the last todo will show empty message + Given the date is "2013-03-11" + And I have a completed todo with description "todo 2" in context "@pc" completed 1 days ago + And I have a completed todo with description "todo 3" in context "@pc" completed 8 days ago + When I go to the done actions page + Then I should see "todo 1" in the done today container + And I should see "todo 2" in the done this week container + And I should see "todo 3" in the done this month container + When I mark the completed todo "todo 1" active + Then I should not see "todo 1" + And I should see empty message for done today of done actions + When I mark the completed todo "todo 2" active + Then I should not see "todo 2" + And I should see empty message for done this week of done actions + When I mark the completed todo "todo 3" active + Then I should not see "todo 3" + And I should see empty message for done this month of done actions + @javascript Scenario Outline: I can toggle the star of a todo from the done pages When I go to the diff --git a/lib/tracks/done_todos.rb b/lib/tracks/done_todos.rb index e5374dab..36e08658 100644 --- a/lib/tracks/done_todos.rb +++ b/lib/tracks/done_todos.rb @@ -1,7 +1,7 @@ class DoneTodos - def self.done_todos_for_container(container) - completed_todos = container.todos.completed - return done_today(completed_todos), done_this_week(completed_todos), done_this_month(completed_todos) + def self.done_todos_for_container(user) + completed_todos = user.todos.completed + return done_today(completed_todos), done_rest_of_week(completed_todos), done_rest_of_month(completed_todos) end def self.done_today(todos, includes = {:include => Todo::DEFAULT_INCLUDES}) @@ -9,14 +9,31 @@ class DoneTodos todos.completed_after(start_of_this_day).all(includes) end - def self.done_this_week(todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + def self.done_rest_of_week(todos, includes = {:include => Todo::DEFAULT_INCLUDES}) done_between(todos, includes, Time.zone.now.beginning_of_day, Time.zone.now.beginning_of_week) end - def self.done_this_month(todos, includes = {:include => Todo::DEFAULT_INCLUDES}) + def self.done_rest_of_month(todos, includes = {:include => Todo::DEFAULT_INCLUDES}) done_between(todos, includes, Time.zone.now.beginning_of_week, Time.zone.now.beginning_of_month) end + def self.completed_period(date) + return nil if date.nil? + + period = nil + period = "rest_of_month" if date > Time.zone.now.beginning_of_month + period = "rest_of_week" if date > Time.zone.now.beginning_of_week + period = "today" if date > Time.zone.now.beginning_of_day + + return period + end + + def self.remaining_in_container(user, period) + count = self.send("done_#{period}", user.todos.completed, {}).count + return nil if period.nil? + return count + end + private def self.done_between(todos, includes, start_date, end_date)