diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb
index c7e46250..9fd7211e 100644
--- a/app/controllers/tasks_controller.rb
+++ b/app/controllers/tasks_controller.rb
@@ -1,21 +1,21 @@
# encoding: utf-8
class TasksController < ApplicationController
#auto_complete_for :user, :nick
-
+
def index
@non_group_tasks = Task.non_group.includes(assignments: :user)
@groups = Workgroup.includes(open_tasks: {assignments: :user})
end
-
+
def user
@unaccepted_tasks = Task.unaccepted_tasks_for(current_user)
@accepted_tasks = Task.accepted_tasks_for(current_user)
end
-
+
def new
@task = Task.new(current_user_id: current_user.id)
end
-
+
def create
@task = Task.new(params[:task])
if params[:periodic]
@@ -27,24 +27,25 @@ class TasksController < ApplicationController
render :template => "tasks/new"
end
end
-
+
def show
@task = Task.find(params[:id])
end
-
+
def edit
@task = Task.find(params[:id])
+ @periodic = !!params[:periodic]
@task.current_user_id = current_user.id
- if @task.periodic?
- flash.now[:alert] = I18n.t('tasks.edit.warning_periodic').html_safe
- end
end
-
+
def update
@task = Task.find(params[:id])
+ task_group = @task.periodic_task_group
was_periodic = @task.periodic?
+ prev_due_date = @task.due_date
@task.attributes=(params[:task])
if @task.errors.empty? && @task.save
+ task_group.update_tasks_including(@task, prev_due_date) if params[:periodic]
flash[:notice] = I18n.t('tasks.update.notice')
if was_periodic && !@task.periodic?
flash[:notice] = I18n.t('tasks.update.notice_converted')
@@ -58,7 +59,7 @@ class TasksController < ApplicationController
render :template => "tasks/edit"
end
end
-
+
def destroy
task = Task.find(params[:id])
# Save user_ids to update apple statistics after destroy
@@ -73,7 +74,7 @@ class TasksController < ApplicationController
redirect_to tasks_url, :notice => I18n.t('tasks.destroy.notice')
end
-
+
# assign current_user to the task and set the assignment to "accepted"
# if there is already an assignment, only accepted will be set to true
def accept
@@ -85,23 +86,23 @@ class TasksController < ApplicationController
end
redirect_to user_tasks_path, :notice => I18n.t('tasks.accept.notice')
end
-
+
# deletes assignment between current_user and given task
def reject
Task.find(params[:id]).users.delete(current_user)
redirect_to :action => "index"
end
-
+
def set_done
Task.find(params[:id]).update_attribute :done, true
redirect_to tasks_url, :notice => I18n.t('tasks.set_done.notice')
end
-
+
# Shows all tasks, which are already done
def archive
@tasks = Task.done.page(params[:page]).per(@per_page).order('tasks.updated_on DESC').includes(assignments: :user)
end
-
+
# shows workgroup (normal group) to edit weekly_tasks_template
def workgroup
@group = Group.find(params[:workgroup_id])
diff --git a/app/models/periodic_task_group.rb b/app/models/periodic_task_group.rb
index 5e8d2e69..b7ccceeb 100644
--- a/app/models/periodic_task_group.rb
+++ b/app/models/periodic_task_group.rb
@@ -25,6 +25,22 @@ class PeriodicTaskGroup < ActiveRecord::Base
end
end
+ def update_tasks_including(template_task, prev_due_date)
+ group_tasks = tasks + [template_task]
+ due_date_delta = template_task.due_date - prev_due_date
+ tasks.each do |task|
+ task.update!(name: template_task.name,
+ description: template_task.description,
+ duration: template_task.duration,
+ required_users: template_task.required_users,
+ workgroup: template_task.workgroup,
+ due_date: task.due_date + due_date_delta)
+ end
+ group_tasks.each do |task|
+ task.update_columns(periodic_task_group_id: self.id)
+ end
+ end
+
protected
# @return [Number] Number of days between two periodic tasks
diff --git a/app/views/tasks/_form.html.haml b/app/views/tasks/_form.html.haml
index 78925c41..077836ba 100644
--- a/app/views/tasks/_form.html.haml
+++ b/app/views/tasks/_form.html.haml
@@ -1,31 +1,11 @@
-- content_for :javascript do
- :javascript
- $(function() {
- $("#task_user_list").tokenInput("#{users_path(:format => :json)}", {
- crossDomain: false,
- prePopulate: $("#task_user_list").data("pre"),
- hintText: '#{escape_javascript(t('.search.hint'))}',
- noResultText: '#{escape_javascript(t('.search.noresult'))}',
- searchingText: '#{escape_javascript(t('.search.placeholder'))}',
- theme: 'facebook'
- });
- });
-
-- content_for :sidebar do
- = render "shared/workgroup_members"
-
-= simple_form_for @task do |f|
- = f.hidden_field :current_user_id
- = f.input :name
- = f.input :description, as: :text, input_html: {rows: 10}
- = f.input :duration, :as => :select, :collection => 1..3
- = f.input :user_list, :as => :string, :input_html => { 'data-pre' => @task.users.map(&:token_attributes).to_json }
- = f.input :required_users
- = f.association :workgroup
- = f.input :due_date, as: :date_picker
- = f.input :done
- .form-actions
- = f.submit class: 'btn btn-primary'
- - if @task.new_record?
- = f.submit t('.submit.periodic'), name: 'periodic', class: 'btn'
- = link_to t('ui.or_cancel'), :back
+= form.hidden_field :current_user_id
+= form.input :name
+= form.input :description, as: :text, input_html: {rows: 10}
+= form.input :duration, :as => :select, :collection => 1..3
+- unless local_assigns[:periodic]
+ = form.input :user_list, :as => :string, :input_html => { 'data-pre' => form.object.users.map(&:token_attributes).to_json }
+= form.input :required_users
+= form.association :workgroup
+= form.input :due_date, as: :date_picker
+- unless local_assigns[:periodic]
+ = form.input :done
diff --git a/app/views/tasks/_form_sidebar.html.haml b/app/views/tasks/_form_sidebar.html.haml
new file mode 100644
index 00000000..c32a6c94
--- /dev/null
+++ b/app/views/tasks/_form_sidebar.html.haml
@@ -0,0 +1,15 @@
+- content_for :javascript do
+ :javascript
+ $(function() {
+ $("#task_user_list").tokenInput("#{users_path(:format => :json)}", {
+ crossDomain: false,
+ prePopulate: $("#task_user_list").data("pre"),
+ hintText: '#{escape_javascript(t('.search.hint'))}',
+ noResultText: '#{escape_javascript(t('.search.noresult'))}',
+ searchingText: '#{escape_javascript(t('.search.placeholder'))}',
+ theme: 'facebook'
+ });
+ });
+
+- content_for :sidebar do
+ = render "shared/workgroup_members"
diff --git a/app/views/tasks/edit.haml b/app/views/tasks/edit.haml
index 624324db..35cd9cb5 100644
--- a/app/views/tasks/edit.haml
+++ b/app/views/tasks/edit.haml
@@ -1,3 +1,15 @@
-- title t('.title')
+- title @periodic ? t('.title_periodic') : t('.title')
-= render 'form'
+- if @task.periodic? && !@periodic
+ .alert.alert-info= raw t('tasks.edit.warning_periodic')
+
+= render 'form_sidebar'
+
+= simple_form_for @task do |form|
+ = render 'form', form: form, periodic: @periodic
+ .form-actions
+ - if @periodic
+ = form.submit t('.submit_periodic'), name: 'periodic', class: 'btn btn-primary'
+ - else
+ = form.submit class: 'btn btn-primary'
+ = link_to t('ui.or_cancel'), :back
diff --git a/app/views/tasks/new.haml b/app/views/tasks/new.haml
index 624324db..277480cf 100644
--- a/app/views/tasks/new.haml
+++ b/app/views/tasks/new.haml
@@ -1,3 +1,10 @@
- title t('.title')
-= render 'form'
+= render 'form_sidebar'
+
+= simple_form_for @task do |form|
+ = render 'form', form: form, periodic: nil
+ .form-actions
+ = form.submit class: 'btn btn-primary'
+ = form.submit t('.submit_periodic'), name: 'periodic', class: 'btn'
+ = link_to t('ui.or_cancel'), :back
diff --git a/app/views/tasks/show.haml b/app/views/tasks/show.haml
index 93f61269..ba7a36d0 100644
--- a/app/views/tasks/show.haml
+++ b/app/views/tasks/show.haml
@@ -10,7 +10,7 @@
%dd= simple_format(@task.description)
- if @task.due_date.present?
%dt= heading_helper Task, :due_date
- %dd
+ %dd
= format_date(@task.due_date)
- if @task.periodic?
%i.icon-repeat{title: t('tasks.repeated')}
@@ -30,8 +30,14 @@
- unless @task.done?
= link_to t('.mark_done'), set_done_task_path(@task), method: :post, class: 'btn'
= link_to t('ui.edit'), edit_task_path(@task), class: 'btn'
- = link_to t('ui.delete'), task_path(@task), :method => :delete, :data => {:confirm => t('.confirm_delete_single')},
- class: 'btn btn-danger'
- if @task.periodic?
- = link_to t('.delete_group'), task_path(@task, periodic: true), method: :delete,
- :data => {confirm: t('.confirm_delete_group')}, class: 'btn btn-danger'
+ = link_to edit_task_path(@task, periodic: true), class: 'btn' do
+ %i.icon.icon-repeat
+ = t('.edit_group')
+ = link_to t('ui.delete'), task_path(@task), method: :delete, class: 'btn btn-danger',
+ data: {confirm: @task.periodic? ? t('.confirm_delete_single_from_group') : t('.confirm_delete_single')}
+ - if @task.periodic?
+ = link_to task_path(@task, periodic: true), method: :delete, class: 'btn btn-danger',
+ data: {confirm: t('.confirm_delete_group')} do
+ %i.icon.icon-repeat
+ = t('.delete_group')
diff --git a/config/locales/en.yml b/config/locales/en.yml
index cda830a9..9c59a84f 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1624,6 +1624,8 @@ en:
notice: Task has been deleted
edit:
title: Edit task
+ title_periodic: Edit recurring task
+ submit_periodic: Save recurring task
warning_periodic: "Warning: This task is part of a group of recurring tasks. When saving it will be excluded from the group and it will be converted to a regular task."
error_not_found: No workgroup found
form:
@@ -1654,6 +1656,7 @@ en:
pages: Pages
new:
title: Create new task
+ submit_periodic: Create recurring task
repeated: Task is recurring
set_done:
notice: The state of the task has been updated
@@ -1661,7 +1664,9 @@ en:
accept_task: Accept task
confirm_delete_group: Really delete this and all subsequent tasks?
confirm_delete_single: Are you sure you want to delete the task?
+ confirm_delete_single_from_group: Are you sure you want to delete this task (and keep related recurring tasks)?
delete_group: Delete task and subsequent
+ edit_group: Edit recurring
hours: "%{count}h"
mark_done: Mark task as done
reject_task: Reject task