add popup for approval to complete the Task [fixes SCI-1200]

This commit is contained in:
zmagod 2017-05-04 12:41:22 +02:00
parent 41df727e57
commit acc5594f1b
8 changed files with 137 additions and 57 deletions

View file

@ -24,6 +24,38 @@ function applyCheckboxCallBack() {
});
}
// Complete mymodule
function complete_my_module_actions() {
var modal = $('#completed-task-modal');
modal.find('[data-action="complete"]')
.off().on().click(function(event) {
event.stopPropagation();
event.preventDefault();
event.stopImmediatePropagation();
$.ajax({
url: modal.data('url'),
type: 'GET',
success: function(data) {
var task_button = $("[data-action='complete-task']");
task_button.attr('data-action', 'uncomplete-task');
task_button.find('.btn')
.removeClass('btn-primary').addClass('btn-greyed');
$('.task-due-date').html(data.module_header_due_date_label);
$('.task-state-label').html(data.module_state_label);
task_button
.find('button')
.html('<span class="glyphicon glyphicon-remove"></span>&nbsp;' +
data.task_button_title);
modal.modal('hide');
},
error: function() {
modal.modal('hide');
}
});
});
}
// Sets callback for completing/uncompleting step
function applyStepCompletedCallBack() {
// First, remove old event handlers, as we use turbolinks
@ -46,14 +78,10 @@ function applyStepCompletedCallBack() {
button = step.find("[data-action='complete-step']");
button.attr("data-action", "uncomplete-step");
button.find(".btn").removeClass("btn-primary").addClass("btn-default");
if (data.task_completed) {
task_button = $("[data-action='complete-task']");
task_button.attr('data-action', 'uncomplete-task');
task_button.find('.btn')
.removeClass('btn-primary').addClass('btn-default');
$('.task-due-date').html(data.module_header_due_date_label);
$('.task-state-label').html(data.module_state_label);
task_button.find('button').html(data.task_button_title);
if (data.task_ready_to_complete) {
$('#completed-task-modal').modal('show');
complete_my_module_actions();
}
}
else {

View file

@ -3,26 +3,27 @@ class MyModulesController < ApplicationController
include TeamsHelper
include InputSanitizeHelper
before_action :load_vars, only: [
:show, :update, :destroy,
:description, :due_date, :protocols, :results,
:samples, :activities, :activities_tab,
:assign_samples, :unassign_samples,
:delete_samples, :toggle_task_state,
:samples_index, :archive]
before_action :load_vars_nested, only: [:new, :create]
before_action :check_edit_permissions, only: [
:update, :description, :due_date
]
before_action :check_destroy_permissions, only: [:destroy]
before_action :check_view_info_permissions, only: [:show]
before_action :check_view_activities_permissions, only: [:activities, :activities_tab]
before_action :check_view_protocols_permissions, only: [:protocols]
before_action :check_view_results_permissions, only: [:results]
before_action :check_view_samples_permissions, only: [:samples, :samples_index]
before_action :check_view_archive_permissions, only: [:archive]
before_action :check_assign_samples_permissions, only: [:assign_samples]
before_action :check_unassign_samples_permissions, only: [:unassign_samples]
before_action :load_vars,
only: %I[show update destroy description due_date protocols
results samples activities activities_tab
assign_samples unassign_samples delete_samples
toggle_task_state samples_index archive
complete_my_module]
before_action :load_vars_nested, only: %I[new create]
before_action :check_edit_permissions,
only: %I[update description due_date]
before_action :check_destroy_permissions, only: :destroy
before_action :check_view_info_permissions, only: :show
before_action :check_view_activities_permissions,
only: %I[activities activities_tab]
before_action :check_view_protocols_permissions, only: :protocols
before_action :check_view_results_permissions, only: :results
before_action :check_view_samples_permissions,
only: %I[samples samples_index]
before_action :check_view_archive_permissions, only: :archive
before_action :check_assign_samples_permissions, only: :assign_samples
before_action :check_unassign_samples_permissions, only: :unassign_samples
before_action :check_complete_my_module_perimission, only: :complete_my_module
layout 'fluid'.freeze
@ -396,6 +397,31 @@ class MyModulesController < ApplicationController
end
end
def complete_my_module
respond_to do |format|
if @my_module.uncompleted? && @my_module.check_completness_status
@my_module.complete
@my_module.save
task_completion_activity
format.json do
render json: {
task_button_title: t('my_modules.buttons.uncomplete'),
module_header_due_date_label: render_to_string(
partial: 'my_modules/module_header_due_date_label.html.erb',
locals: { my_module: @my_module }
),
module_state_label: render_to_string(
partial: 'my_modules/module_state_label.html.erb',
locals: { my_module: @my_module }
)
}, status: :ok
end
else
format.json { render json: {}, status: :unprocessable_entity }
end
end
end
private
def task_completion_activity
@ -485,6 +511,10 @@ class MyModulesController < ApplicationController
end
end
def check_complete_my_module_perimission
render_403 unless can_complete_module(@my_module)
end
def my_module_params
params.require(:my_module).permit(:name, :description, :due_date,
:archived)

View file

@ -330,10 +330,13 @@ class StepsController < ApplicationController
respond_to do |format|
if step
completed = params[:completed] == "true"
completed = params[:completed] == 'true'
protocol = step.protocol
authorized = ((completed and can_complete_step_in_protocol(protocol)) or (!completed and can_uncomplete_step_in_protocol(protocol)))
authorized = (
(completed and can_complete_step_in_protocol(protocol)) ||
(!completed and can_uncomplete_step_in_protocol(protocol))
)
if authorized
changed = step.completed != completed
@ -346,15 +349,15 @@ class StepsController < ApplicationController
if step.save
if protocol.in_module?
task_completed = protocol.my_module.check_completness
ready_to_complete = protocol.my_module.check_completness_status
end
# Create activity
if changed
completed_steps = protocol.steps.where(completed: true).count
all_steps = protocol.steps.count
str = completed ? "activities.complete_step" :
"activities.uncomplete_step"
str = 'activities.uncomplete_step'
str = 'activities.complete_step' if completed
message = t(
str,
@ -386,27 +389,14 @@ class StepsController < ApplicationController
else
t('protocols.steps.options.uncomplete_title')
end
task_button_title =
t('my_modules.buttons.uncomplete') if task_completed
format.json do
if task_completed
if ready_to_complete && protocol.my_module.uncompleted?
render json: {
new_title: localized_title,
task_completed: task_completed,
task_button_title: task_button_title,
module_header_due_date_label: render_to_string(
partial: 'my_modules/module_header_due_date_label.html.erb',
locals: { my_module: step.protocol.my_module }
),
module_state_label: render_to_string(
partial: 'my_modules/module_state_label.html.erb',
locals: { my_module: step.protocol.my_module }
)
},
status: :accepted
task_ready_to_complete: true,
new_title: localized_title
}, status: :ok
else
render json: { new_title: localized_title },
status: :accepted
render json: { new_title: localized_title }, status: :ok
end
end
else

View file

@ -374,17 +374,14 @@ class MyModule < ActiveRecord::Base
state == 'completed'
end
# Mark task completed if all steps become completed
def check_completness
# Check if my_module is ready to become completed
def check_completness_status
if protocol && protocol.steps.count > 0
completed = true
protocol.steps.find_each do |step|
completed = false unless step.completed
end
if completed
update_attributes(state: 'completed', completed_on: DateTime.now)
return true
end
return true if completed
end
false
end

View file

@ -0,0 +1,28 @@
<div class="modal fade"
tabindex="-1"
role="dialog"
data-url="<%= complete_my_module_my_module_path(@my_module) %>"
id="completed-task-modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title"><%=t 'my_modules.buttons.complete' %></h4>
</div>
<div class="modal-body">
<p><%=t 'my_modules.complete_modal.description' %></p>
</div>
<div class="modal-footer">
<button type="button"
class="btn btn-primary"
data-action="complete"><%=t 'my_modules.buttons.complete' %></button>
<button type="button"
class="btn btn-default"
data-dismiss="modal"><%=t 'my_modules.complete_modal.leave_uncompleted' %></button>
</div>
</div>
</div>
</div>

View file

@ -44,5 +44,8 @@
<!-- Image preview modal -->
<%= render partial: "shared/image_preview_modal.html.erb" %>
<!-- Complete task modal -->
<%= render partial: 'my_modules/complete_task_modal.html.erb' %>
<%= stylesheet_link_tag 'datatables' %>
<%= javascript_include_tag("my_modules/protocols") %>

View file

@ -432,6 +432,9 @@ en:
buttons:
complete: "Complete task"
uncomplete: "Uncomplete task"
complete_modal:
description: 'You have completed all steps in the task. Would you like to mark entire task as completed?'
leave_uncompleted: 'Leave task in progress'
description:
title: "Edit task %{module} description"
label: "Description"

View file

@ -283,6 +283,7 @@ Rails.application.routes.draw do
get 'results' # Results view for single module
get 'samples' # Samples view for single module
get 'archive' # Archive view for single module
get 'complete_my_module'
post 'toggle_task_state'
# Renders sample datatable for single module (ajax action)
post 'samples_index'